@ghostry/fabricator 0.0.1 → 0.0.3

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.
Files changed (139) hide show
  1. package/README.md +18 -12
  2. package/dist/esm/Adapter/Core.js +3 -3
  3. package/dist/esm/Enumeration/Enumerate.js +16 -13
  4. package/dist/esm/Error/index.js +16 -8
  5. package/dist/esm/Fabricator/Constructor.js +12 -14
  6. package/dist/esm/Harnessing/Core.js +30 -0
  7. package/dist/esm/Harnessing/Salt.js +12 -0
  8. package/dist/esm/Harnessing/Types.js +1 -0
  9. package/dist/esm/Instance/Core.js +25 -41
  10. package/dist/esm/Instance/Stack/Async.js +10 -0
  11. package/dist/esm/Instance/Stack/Sync.js +16 -0
  12. package/dist/esm/Primitive/bigint/Registry.js +12 -12
  13. package/dist/esm/Primitive/boolean/Registry.js +2 -1
  14. package/dist/esm/Primitive/date/Registry.js +15 -14
  15. package/dist/esm/Primitive/null/Registry.js +2 -1
  16. package/dist/esm/Primitive/number/Registry.js +18 -17
  17. package/dist/esm/Primitive/recursive/Fabricator.js +1 -1
  18. package/dist/esm/Primitive/symbol/Registry.js +2 -1
  19. package/dist/esm/Primitive/undefined/Registry.js +2 -1
  20. package/dist/esm/Random/index.js +24 -79
  21. package/dist/esm/Utility/Core.js +6 -1
  22. package/dist/esm/adapting.js +2 -0
  23. package/dist/esm/harnessing.js +1 -0
  24. package/dist/esm/index.js +5 -4
  25. package/dist/esm/internal.js +2 -2
  26. package/dist/types/Adapter/Core.d.ts +30 -33
  27. package/dist/types/Adapter/Types.d.ts +78 -88
  28. package/dist/types/Bound.d.ts +15 -15
  29. package/dist/types/Distribution/index.d.ts +54 -61
  30. package/dist/types/Enumeration/Enumerate.d.ts +24 -24
  31. package/dist/types/Enumeration/Plan.d.ts +22 -26
  32. package/dist/types/Enumeration/Types.d.ts +38 -43
  33. package/dist/types/Error/index.d.ts +103 -89
  34. package/dist/types/Fabricator/Constructor.d.ts +24 -26
  35. package/dist/types/Fabricator/Types.d.ts +73 -81
  36. package/dist/types/Harnessing/Core.d.ts +43 -0
  37. package/dist/types/Harnessing/Salt.d.ts +31 -0
  38. package/dist/types/Harnessing/Types.d.ts +79 -0
  39. package/dist/types/Instance/Core.d.ts +38 -74
  40. package/dist/types/Instance/Stack/Async.d.ts +14 -0
  41. package/dist/types/Instance/Stack/Sync.d.ts +14 -0
  42. package/dist/types/Instance/Types.d.ts +98 -102
  43. package/dist/types/Primitive/always/Schema.d.ts +8 -8
  44. package/dist/types/Primitive/always/Types.d.ts +7 -7
  45. package/dist/types/Primitive/array/Registry.d.ts +10 -8
  46. package/dist/types/Primitive/array/Schema.d.ts +4 -5
  47. package/dist/types/Primitive/array/Types.d.ts +6 -6
  48. package/dist/types/Primitive/bigint/Registry.d.ts +6 -6
  49. package/dist/types/Primitive/bigint/Schema.d.ts +8 -8
  50. package/dist/types/Primitive/bigint/Types.d.ts +5 -5
  51. package/dist/types/Primitive/boolean/Outcomes.d.ts +8 -8
  52. package/dist/types/Primitive/boolean/Registry.d.ts +2 -12
  53. package/dist/types/Primitive/boolean/Schema.d.ts +8 -8
  54. package/dist/types/Primitive/boolean/Types.d.ts +3 -3
  55. package/dist/types/Primitive/choice/Fabricator.d.ts +6 -7
  56. package/dist/types/Primitive/choice/Registry.d.ts +13 -13
  57. package/dist/types/Primitive/choice/Schema.d.ts +6 -6
  58. package/dist/types/Primitive/choice/Types.d.ts +11 -11
  59. package/dist/types/Primitive/date/Registry.d.ts +25 -48
  60. package/dist/types/Primitive/date/Schema.d.ts +9 -10
  61. package/dist/types/Primitive/date/Types.d.ts +4 -4
  62. package/dist/types/Primitive/enum/Registry.d.ts +13 -13
  63. package/dist/types/Primitive/enum/Schema.d.ts +5 -5
  64. package/dist/types/Primitive/enum/Types.d.ts +17 -19
  65. package/dist/types/Primitive/namespace.d.ts +10 -10
  66. package/dist/types/Primitive/null/Registry.d.ts +2 -2
  67. package/dist/types/Primitive/null/Schema.d.ts +2 -2
  68. package/dist/types/Primitive/null/Types.d.ts +3 -3
  69. package/dist/types/Primitive/nullable/Fabricator.d.ts +7 -7
  70. package/dist/types/Primitive/nullable/Schema.d.ts +13 -13
  71. package/dist/types/Primitive/nullable/Types.d.ts +9 -10
  72. package/dist/types/Primitive/nullish/Fabricator.d.ts +12 -13
  73. package/dist/types/Primitive/nullish/Schema.d.ts +8 -8
  74. package/dist/types/Primitive/nullish/Types.d.ts +12 -13
  75. package/dist/types/Primitive/number/Registry.d.ts +20 -38
  76. package/dist/types/Primitive/number/Schema.d.ts +11 -12
  77. package/dist/types/Primitive/number/Types.d.ts +13 -13
  78. package/dist/types/Primitive/number/defaults.d.ts +3 -3
  79. package/dist/types/Primitive/object/Fabricator.d.ts +15 -15
  80. package/dist/types/Primitive/object/Registry.d.ts +8 -8
  81. package/dist/types/Primitive/object/Schema.d.ts +10 -10
  82. package/dist/types/Primitive/object/Types.d.ts +20 -22
  83. package/dist/types/Primitive/object/compute/Fabricator.d.ts +4 -5
  84. package/dist/types/Primitive/object/compute/Schema.d.ts +4 -4
  85. package/dist/types/Primitive/object/compute/Types.d.ts +19 -20
  86. package/dist/types/Primitive/object/omittable/Fabricator.d.ts +10 -10
  87. package/dist/types/Primitive/object/omittable/Outcomes.d.ts +2 -2
  88. package/dist/types/Primitive/object/omittable/Schema.d.ts +11 -11
  89. package/dist/types/Primitive/object/omittable/Types.d.ts +14 -15
  90. package/dist/types/Primitive/object/optional/Fabricator.d.ts +16 -18
  91. package/dist/types/Primitive/object/optional/Outcomes.d.ts +2 -2
  92. package/dist/types/Primitive/object/optional/Schema.d.ts +4 -4
  93. package/dist/types/Primitive/object/optional/Types.d.ts +17 -17
  94. package/dist/types/Primitive/opaque/Registry.d.ts +3 -3
  95. package/dist/types/Primitive/opaque/Schema.d.ts +8 -9
  96. package/dist/types/Primitive/record/Registry.d.ts +8 -6
  97. package/dist/types/Primitive/record/Schema.d.ts +9 -11
  98. package/dist/types/Primitive/record/Types.d.ts +25 -25
  99. package/dist/types/Primitive/recursive/Fabricator.d.ts +20 -21
  100. package/dist/types/Primitive/recursive/Registry.d.ts +6 -7
  101. package/dist/types/Primitive/recursive/Schema.d.ts +8 -8
  102. package/dist/types/Primitive/recursive/Terminate.d.ts +13 -14
  103. package/dist/types/Primitive/recursive/Types.d.ts +31 -31
  104. package/dist/types/Primitive/recursive/self/Fabricator.d.ts +11 -12
  105. package/dist/types/Primitive/recursive/self/Schema.d.ts +10 -10
  106. package/dist/types/Primitive/recursive/self/Types.d.ts +7 -8
  107. package/dist/types/Primitive/string/Constants.d.ts +12 -13
  108. package/dist/types/Primitive/string/Fabricator.d.ts +2 -2
  109. package/dist/types/Primitive/string/Registry.d.ts +10 -16
  110. package/dist/types/Primitive/string/Schema.d.ts +5 -5
  111. package/dist/types/Primitive/string/Types.d.ts +17 -17
  112. package/dist/types/Primitive/symbol/Fabricator.d.ts +2 -2
  113. package/dist/types/Primitive/symbol/Registry.d.ts +4 -11
  114. package/dist/types/Primitive/symbol/Schema.d.ts +6 -6
  115. package/dist/types/Primitive/symbol/Types.d.ts +2 -2
  116. package/dist/types/Primitive/tuple/Fabricator.d.ts +7 -8
  117. package/dist/types/Primitive/tuple/Schema.d.ts +5 -5
  118. package/dist/types/Primitive/tuple/Types.d.ts +24 -25
  119. package/dist/types/Primitive/undefinable/Fabricator.d.ts +7 -7
  120. package/dist/types/Primitive/undefinable/Schema.d.ts +13 -13
  121. package/dist/types/Primitive/undefinable/Types.d.ts +10 -10
  122. package/dist/types/Primitive/undefined/Registry.d.ts +2 -2
  123. package/dist/types/Primitive/undefined/Schema.d.ts +4 -4
  124. package/dist/types/Primitive/undefined/Types.d.ts +3 -3
  125. package/dist/types/Random/Generator/sfc32.d.ts +4 -4
  126. package/dist/types/Random/Types.d.ts +151 -293
  127. package/dist/types/Random/index.d.ts +56 -81
  128. package/dist/types/Schema/Core.d.ts +19 -21
  129. package/dist/types/Schema/Registry.d.ts +3 -3
  130. package/dist/types/Schema/Types.d.ts +41 -48
  131. package/dist/types/Types.d.ts +39 -45
  132. package/dist/types/Utility/Core.d.ts +18 -9
  133. package/dist/types/adapting.d.ts +32 -0
  134. package/dist/types/harnessing.d.ts +30 -0
  135. package/dist/types/index.d.ts +95 -128
  136. package/dist/types/internal.d.ts +53 -40
  137. package/package.json +39 -7
  138. package/dist/esm/Random/CallSite.js +0 -56
  139. package/dist/types/Random/CallSite.d.ts +0 -59
@@ -1,13 +1,12 @@
1
1
  import type { Stream } from "../Random/Types";
2
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.
3
+ * How randomly generated values cluster within a `{ min, max }` range. Without
4
+ * one, generation is uniform — every value in the range is equally likely.
6
5
  *
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.
6
+ * Each variant is a tagged object so distributions stay introspectable and
7
+ * serializable. The `custom` variant is the escape hatch: a shaping function
8
+ * `(u) => p` mapping a uniform draw in `[0, 1)` to a position in `[0, 1)`
9
+ * within the range.
11
10
  */
12
11
  export type Distribution = Distribution.Uniform | Distribution.Normal | Distribution.Skew | Distribution.Triangular | Distribution.Logarithmic | Distribution.Multi | Distribution.Custom;
13
12
  export type Range = {
@@ -25,9 +24,9 @@ export declare namespace Distribution {
25
24
  spread?: number | undefined;
26
25
  };
27
26
  /**
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.
27
+ * Bell curve truncated to the range. `mean` defaults to the range's center;
28
+ * `spread` (standard deviation) defaults to a sixth of the span, placing the
29
+ * bounds at roughly ±3σ before truncation.
31
30
  */
32
31
  const normal: (params?: {
33
32
  mean?: number;
@@ -38,8 +37,8 @@ export declare namespace Distribution {
38
37
  exponent: number;
39
38
  };
40
39
  /**
41
- * Power curve. `exponent > 1` biases toward `min`, `exponent < 1`
42
- * biases toward `max`, and `exponent === 1` is uniform.
40
+ * Power curve. `exponent > 1` biases toward `min`, `exponent < 1` biases
41
+ * toward `max`, and `exponent === 1` is uniform.
43
42
  */
44
43
  const skew: (exponent: number) => Distribution;
45
44
  type Triangular = {
@@ -56,10 +55,9 @@ export declare namespace Distribution {
56
55
  kind: "logarithmic";
57
56
  };
58
57
  /**
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.
58
+ * Log-uniform (reciprocal): density proportional to `1/x`, so values spread
59
+ * evenly across orders of magnitude and cluster toward `min`. Requires a
60
+ * strictly positive range — the logarithm is undefined at or below zero.
63
61
  */
64
62
  const logarithmic: () => Distribution;
65
63
  type Multi = {
@@ -70,11 +68,10 @@ export declare namespace Distribution {
70
68
  }>;
71
69
  };
72
70
  /**
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.
71
+ * A weighted blend of component distributions, each drawn over the same
72
+ * range. Localized components with distinct centers (e.g. two `normal`s at
73
+ * different means) produce the separate peaks of a multimodal distribution.
74
+ * Weights are relative — they need not sum to 1.
78
75
  */
79
76
  const multi: (components: ReadonlyArray<{
80
77
  weight: number;
@@ -85,73 +82,69 @@ export declare namespace Distribution {
85
82
  shape: (u: number) => number;
86
83
  };
87
84
  /**
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.
85
+ * Escape hatch: `shape` maps a uniform draw in `[0, 1)` to a position in `[0,
86
+ * 1)` within the range (an inverse CDF). The output is clamped to `[0, 1]` so
87
+ * the result always lands within the bounds.
92
88
  */
93
89
  const custom: (shape: (u: number) => number) => Distribution;
94
90
  }
95
91
  /**
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.
92
+ * Build a sampler that draws values within `range` following `distribution`.
93
+ * Each call consumes one fresh uniform draw and, by construction, returns a
94
+ * value within `[min, max]` — distributions with mass outside the range (e.g. a
95
+ * normal's tails) are truncated via their inverse CDF rather than rejected or
96
+ * clamped.
101
97
  */
102
98
  export declare function sampler(distribution: Distribution, range: Range, stream: Stream): () => number;
103
99
  export declare function sample<$T>(list: ReadonlyArray<$T>, stream: Stream): $T;
104
100
  /**
105
101
  * 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.
102
+ * uniformly random order — every permutation is equally likely. Does not mutate
103
+ * `items`, matching `sample`/`weighted`'s read-only convention.
109
104
  */
110
105
  export declare function shuffle<$T>(items: ReadonlyArray<$T>, stream: Stream): $T[];
111
106
  /**
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`.
107
+ * `weighted()`'s own inclusion rule: whether this entry stays in the draw
108
+ * table. `0` is valid and disables the outcome; negative/`NaN` are rejected
109
+ * earlier by {@link isValidWeight}. Exposed so `Enumeration/Plan.ts` and the
110
+ * construction guards share one definition of "will this be drawn" rather than
111
+ * each writing `weight > 0`.
118
112
  */
119
113
  export declare function isDrawable(weight: number): boolean;
120
114
  /**
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.
115
+ * Whether a weight is _expressible_ at all, as opposed to whether it is
116
+ * drawable. `0` is valid and disables the outcome; a negative weight or `NaN`
117
+ * is a mistake. `Infinity` is rejected because it cannot be summed into a
118
+ * usable draw table — every cumulative bound becomes `Infinity`, so
119
+ * `weighted()`'s `x < weight` scan matches nothing.
126
120
  */
127
121
  export declare function isValidWeight(weight: number): boolean;
128
122
  /**
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.
123
+ * Outcomes that still have a positive weight after applying the baseline of `1`
124
+ * for any unspecified (missing or explicitly `undefined`) key. The one home of
125
+ * that `?? 1` default, so `assertDrawableKeyedWeights` and
126
+ * `Enumeration/Plan.ts` cannot drift.
133
127
  */
134
128
  export declare function drawableOutcomes<$Outcome extends string>(outcomes: ReadonlyArray<$Outcome>, weights: Readonly<Record<string, number | undefined>> | undefined): ReadonlyArray<$Outcome>;
135
129
  /**
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
130
+ * Two-stage guard for a `[weight, item]` list (`enum`/`choice`'s `.weighted()`
131
+ * registries). Stage 1 rejects any entry that is not {@link isValidWeight};
132
+ * stage 2 rejects a list with no {@link isDrawable} entry left. `label` names
133
+ * the call site (`"T.enum.weighted"`/`"T.choice.weighted"`), `noun` the kind of
141
134
  * entry (`"member"`/`"option"`).
142
135
  */
143
136
  export declare function assertDrawableWeights(label: string, noun: string, items: ReadonlyArray<readonly [number, unknown]>): void;
144
137
  /**
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`/
138
+ * The same two-stage guard as {@link assertDrawableWeights}, for the kinds
139
+ * whose `.weighted(...)` weighs a _fixed, named_ outcome set (`boolean`'s
140
+ * `true`/`false`; `nullable`/`nullish`/`undefinable`/
148
141
  * `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`.
142
+ * caller-supplied list. Stage 2 must see the kind's **full** outcome list — an
143
+ * omitted key still defaults to `1` — hence `outcomes`.
151
144
  *
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.
145
+ * An explicitly-`undefined` value means "unspecified" — `Weights`' keys are all
146
+ * optional and fall back to a baseline of `1` — so it is skipped in stage 1 and
147
+ * defaulted in stage 2.
155
148
  */
156
149
  export declare function assertDrawableKeyedWeights<$Outcome extends string>(label: string, outcomes: ReadonlyArray<$Outcome>, weights: Readonly<Record<string, number | undefined>>): void;
157
150
  export declare function weighted<const $Item>(weights: ReadonlyArray<readonly [number, $Item]>, stream: Stream, label: string): () => $Item;
@@ -2,32 +2,32 @@ import type { Stack } from "../Instance/Types";
2
2
  import type { RandomSource } from "../Random/Types";
3
3
  import type { Enumerable, Limits } from "./Types";
4
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`/
5
+ * Typed `combinatorial`/`coverage` boundary, closing over one instance's
6
+ * `source` and its already-validated `limits` — same shape as
7
+ * `Constructor(source, stack)`. No separate `clock`: `source` already carries
8
+ * its resolved clock (`Random/Types.ts`'s `Options.clock`), so `Constructor`'s
9
+ * `toConstructionContext` reads it off whichever root a construction resolves
10
+ * against. `plan`/ `resolve` (`./Plan.ts`) do the untyped recursive work; this
11
+ * is the one precisely-typed layer, mirroring `Constructor.ts`'s `make`/
13
12
  * `construct` split.
14
13
  *
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.
14
+ * Two derived salts — one per API — each composed from the _effective_ source's
15
+ * salt (`effectiveSource()` below — the active `wrap` frame's, or this
16
+ * instance's `source`; read fresh on every `combinatorial(...)`/`coverage(...)`
17
+ * call, not once when `enumerables()` was built, so the same `combinatorial`
18
+ * reference behaves differently inside an active `wrap`). Each build pins that
19
+ * salt via `new Fabricator(schema, { salt })` (see `Constructor.ts`'s
20
+ * `construct()`) — a pin, not a fork — so every rebuild of one schema draws
21
+ * from the same universe, distinct from anything built under the instance's own
22
+ * salt.
23
+ *
24
+ * `ordinal: null` is pinned alongside it, and is not incidental: a salt says
25
+ * nothing about ordering, so without this pin each lazy rebuild would take the
26
+ * next ordinal from the effective source's counter — advancing it for every
27
+ * later construction, and giving each pass over the `Iterable` a different
28
+ * ordinal. A pinned ordinal is taken verbatim, so the counter is untouched,
29
+ * every iteration rebuilds from the same explicit identity, and the `null` can
30
+ * never coincide with a counted construction.
31
31
  */
32
32
  export declare function enumerables(source: RandomSource, limits: Limits, stack: Stack): {
33
33
  combinatorial: Enumerable;
@@ -7,38 +7,34 @@ type Planning = {
7
7
  orderer: Orderer;
8
8
  };
9
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.
10
+ * Enumerable shape of a built Fabricator tree: how many distinct combinations,
11
+ * and how to reproduce the `index`-th as a `Pin`. Exhaustive kind dispatch
12
+ * lives in `axisFor`; this wrapper applies `"cycle"` permutation uniformly,
13
+ * once, to whatever axis `axisFor` computes — so every recursive call
14
+ * (`axisFor` cases call back into `plan`, never `axisFor` directly) gets its
15
+ * _own_ independent permutation, decorrelating equal-width siblings without any
16
+ * per-kind case needing to know strategy beyond `Strategy`'s own widen/narrow
17
+ * rules.
19
18
  *
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.
19
+ * Width is a function of schema shape _and_ weights: a zero-weighted outcome is
20
+ * not fabricable, so `axisFor` filters through `isDrawable` /
21
+ * `drawableOutcomes` rather than treating the declared branch set as the axis.
22
+ * Without that, `coverage()` would pin a value `fabricate()` can never produce.
23
+ * Defaulting of unspecified keyed weights goes through `drawableOutcomes` so
24
+ * the `?? 1` baseline is never re-implemented here.
27
25
  *
28
26
  * 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.
27
+ * (mixed-radix decode already visits every combination, so permuting would only
28
+ * reorder identical output — see `Orderer`). `orders` is therefore only ever
29
+ * read when `strategy === "cycle"` and is safe to omit otherwise.
33
30
  */
34
31
  export declare function plan(node: Resolvable, planning: Planning): Axis;
35
32
  /**
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.
33
+ * Reproduce the value a `Pin` describes against the built Fabricator it was
34
+ * planned from. `pin === undefined` is universal — `plan()` gave this node a
35
+ * width-1 axis, so there is nothing to pin and it fabricates normally. Every
36
+ * other case only arises for kinds `plan()` treats as enumerable axes, so this
37
+ * switch does not need to be exhaustive the way `plan()`'s is.
42
38
  */
43
39
  export declare function resolve(node: Resolvable, pin: Pin): unknown;
44
40
  export {};
@@ -3,38 +3,35 @@ import type { AnySchema, ValueOf } from "../Schema/Types";
3
3
  import type { Children, Kind, Meta } from "../Types";
4
4
  import type { PlainObject } from "../Utility/Types";
5
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.
6
+ * How a composite with more than one child combines their widths. `"product"`
7
+ * is the cartesian product — width is the product of every child's width;
8
+ * `at(index)` mixed-radix decodes to a full combination (`combinatorial`).
9
+ * `"cycle"` (`coverage`) takes the widest child as the composite's width,
10
+ * cycling narrower children to fill it — see CLAUDE.md's "sum vs product" note
11
+ * for why cycling only ever applies to `object`/`tuple` and never to a sum node
12
+ * (`choice`, the presence wrappers), which always total their children's widths
13
+ * regardless of strategy.
15
14
  */
16
15
  export type Strategy = "product" | "cycle";
17
16
  /**
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.
17
+ * A fresh, reproducible permutation of `0..width-1` each call — one per
18
+ * width-`>1` node `plan()` visits, in walk order, so two nodes of the same
19
+ * width never receive the same permutation (which would otherwise iterate them
20
+ * in lockstep — see CLAUDE.md's note on why a constant phase offset isn't
21
+ * enough). Only consulted under `"cycle"`; `"product"`'s mixed-radix decode
22
+ * already visits every combination, so permuting there would only reorder
23
+ * identical output. Built in `Enumerate.ts` (which can reach `Random/`), then
24
+ * threaded through `plan()` as data — `Plan.ts` stays a total function and
25
+ * never imports randomness.
28
26
  */
29
27
  export type Orderer = (width: bigint) => ReadonlyArray<bigint>;
30
28
  /**
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.
29
+ * Recipe for one enumerated combination against a built Fabricator tree:
30
+ * `undefined` for a drawn (not chosen) node — fabricate normally; `{ value }`
31
+ * for a literal (enum member, boolean, `null`, `undefined`, `Omitted`); `{
32
+ * slots }`/`{ fields }` for a tuple/object, recursing per position/key; `{
33
+ * branch, inner }` for a choice's chosen option, or a presence wrapper's
34
+ * "present" arm, recursing into whichever child was picked.
38
35
  */
39
36
  export type Pin = undefined | {
40
37
  value: unknown;
@@ -47,35 +44,33 @@ export type Pin = undefined | {
47
44
  inner: Pin;
48
45
  };
49
46
  /**
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.
47
+ * One enumerable dimension: how many distinct outcomes, and the `Pin` for the
48
+ * `index`-th (`0 <= index < width`). Widths are `bigint` so a schema with many
49
+ * combined axes can be counted exactly — a `number` would silently lose
50
+ * precision past `Number.MAX_SAFE_INTEGER` and eventually overflow to
51
+ * `Infinity`, which would make a combinatorial limit's error message state a
52
+ * false count.
56
53
  */
57
54
  export type Axis = {
58
55
  readonly width: bigint;
59
56
  readonly at: (index: bigint) => Pin;
60
57
  };
61
58
  /**
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
59
+ * Resolved, already-validated enumeration limits — `initialize()` is where
60
+ * `limits.combinatorial` is defaulted and checked (`Number.isSafeInteger(limit)
61
+ * && limit >= 1`), so `Enumerate()` always receives a value it can trust
62
+ * without re-validating. `coverage` carries no limit here: its count is the
63
+ * widest single axis, linear in the schema as written rather than a product, so
68
64
  * there is nothing for a limit to protect against.
69
65
  */
70
66
  export type Limits = {
71
67
  combinatorial: number;
72
68
  };
73
69
  /**
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`.
70
+ * The shape both `combinatorial` and `coverage` share — strategy and limit
71
+ * differ internally, neither visible here. Takes a Schema, not a built
72
+ * Fabricator: `AnySchema` excludes `Fabricator<any>` (which carries no
73
+ * `[Produces]`), so `ValueOf` can't silently degrade to `unknown`.
79
74
  */
80
75
  export type Enumerable = <const $Schema extends AnySchema>(schema: $Schema) => Iterable<ValueOf<$Schema>>;
81
76
  export type Resolvable = {