@ghostry/fabricator 0.0.1 → 0.0.2

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 (124) hide show
  1. package/README.md +1 -7
  2. package/dist/esm/Error/index.js +8 -0
  3. package/dist/esm/Instance/Core.js +8 -17
  4. package/dist/esm/Instance/Stack/Async.js +10 -0
  5. package/dist/esm/Instance/Stack/Sync.js +16 -0
  6. package/dist/esm/Primitive/bigint/Registry.js +12 -12
  7. package/dist/esm/Primitive/boolean/Registry.js +2 -1
  8. package/dist/esm/Primitive/date/Registry.js +15 -14
  9. package/dist/esm/Primitive/null/Registry.js +2 -1
  10. package/dist/esm/Primitive/number/Registry.js +18 -17
  11. package/dist/esm/Primitive/symbol/Registry.js +2 -1
  12. package/dist/esm/Primitive/undefined/Registry.js +2 -1
  13. package/dist/esm/Random/CallSite.js +27 -13
  14. package/dist/esm/Utility/Core.js +6 -1
  15. package/dist/esm/index.js +4 -2
  16. package/dist/esm/internal.js +2 -1
  17. package/dist/types/Adapter/Core.d.ts +29 -32
  18. package/dist/types/Adapter/Types.d.ts +78 -88
  19. package/dist/types/Bound.d.ts +15 -15
  20. package/dist/types/Distribution/index.d.ts +54 -61
  21. package/dist/types/Enumeration/Enumerate.d.ts +21 -23
  22. package/dist/types/Enumeration/Plan.d.ts +22 -26
  23. package/dist/types/Enumeration/Types.d.ts +38 -43
  24. package/dist/types/Error/index.d.ts +94 -76
  25. package/dist/types/Fabricator/Constructor.d.ts +23 -25
  26. package/dist/types/Fabricator/Types.d.ts +73 -81
  27. package/dist/types/Instance/Core.d.ts +54 -73
  28. package/dist/types/Instance/Stack/Async.d.ts +14 -0
  29. package/dist/types/Instance/Stack/Sync.d.ts +14 -0
  30. package/dist/types/Instance/Types.d.ts +91 -89
  31. package/dist/types/Primitive/always/Schema.d.ts +8 -8
  32. package/dist/types/Primitive/always/Types.d.ts +7 -7
  33. package/dist/types/Primitive/array/Registry.d.ts +10 -8
  34. package/dist/types/Primitive/array/Schema.d.ts +4 -5
  35. package/dist/types/Primitive/array/Types.d.ts +6 -6
  36. package/dist/types/Primitive/bigint/Registry.d.ts +6 -6
  37. package/dist/types/Primitive/bigint/Schema.d.ts +8 -8
  38. package/dist/types/Primitive/bigint/Types.d.ts +5 -5
  39. package/dist/types/Primitive/boolean/Outcomes.d.ts +8 -8
  40. package/dist/types/Primitive/boolean/Registry.d.ts +2 -12
  41. package/dist/types/Primitive/boolean/Schema.d.ts +8 -8
  42. package/dist/types/Primitive/boolean/Types.d.ts +3 -3
  43. package/dist/types/Primitive/choice/Fabricator.d.ts +6 -7
  44. package/dist/types/Primitive/choice/Registry.d.ts +13 -13
  45. package/dist/types/Primitive/choice/Schema.d.ts +6 -6
  46. package/dist/types/Primitive/choice/Types.d.ts +11 -11
  47. package/dist/types/Primitive/date/Registry.d.ts +25 -48
  48. package/dist/types/Primitive/date/Schema.d.ts +9 -10
  49. package/dist/types/Primitive/date/Types.d.ts +4 -4
  50. package/dist/types/Primitive/enum/Registry.d.ts +13 -13
  51. package/dist/types/Primitive/enum/Schema.d.ts +5 -5
  52. package/dist/types/Primitive/enum/Types.d.ts +17 -19
  53. package/dist/types/Primitive/namespace.d.ts +10 -10
  54. package/dist/types/Primitive/null/Registry.d.ts +2 -2
  55. package/dist/types/Primitive/null/Schema.d.ts +2 -2
  56. package/dist/types/Primitive/null/Types.d.ts +3 -3
  57. package/dist/types/Primitive/nullable/Fabricator.d.ts +7 -7
  58. package/dist/types/Primitive/nullable/Schema.d.ts +13 -13
  59. package/dist/types/Primitive/nullable/Types.d.ts +9 -10
  60. package/dist/types/Primitive/nullish/Fabricator.d.ts +12 -13
  61. package/dist/types/Primitive/nullish/Schema.d.ts +8 -8
  62. package/dist/types/Primitive/nullish/Types.d.ts +12 -13
  63. package/dist/types/Primitive/number/Registry.d.ts +20 -38
  64. package/dist/types/Primitive/number/Schema.d.ts +11 -12
  65. package/dist/types/Primitive/number/Types.d.ts +13 -13
  66. package/dist/types/Primitive/number/defaults.d.ts +3 -3
  67. package/dist/types/Primitive/object/Fabricator.d.ts +15 -15
  68. package/dist/types/Primitive/object/Registry.d.ts +8 -8
  69. package/dist/types/Primitive/object/Schema.d.ts +10 -10
  70. package/dist/types/Primitive/object/Types.d.ts +20 -22
  71. package/dist/types/Primitive/object/compute/Fabricator.d.ts +4 -5
  72. package/dist/types/Primitive/object/compute/Schema.d.ts +4 -4
  73. package/dist/types/Primitive/object/compute/Types.d.ts +19 -20
  74. package/dist/types/Primitive/object/omittable/Fabricator.d.ts +10 -10
  75. package/dist/types/Primitive/object/omittable/Outcomes.d.ts +2 -2
  76. package/dist/types/Primitive/object/omittable/Schema.d.ts +11 -11
  77. package/dist/types/Primitive/object/omittable/Types.d.ts +14 -15
  78. package/dist/types/Primitive/object/optional/Fabricator.d.ts +16 -18
  79. package/dist/types/Primitive/object/optional/Outcomes.d.ts +2 -2
  80. package/dist/types/Primitive/object/optional/Schema.d.ts +4 -4
  81. package/dist/types/Primitive/object/optional/Types.d.ts +17 -17
  82. package/dist/types/Primitive/opaque/Registry.d.ts +3 -3
  83. package/dist/types/Primitive/opaque/Schema.d.ts +8 -9
  84. package/dist/types/Primitive/record/Registry.d.ts +8 -6
  85. package/dist/types/Primitive/record/Schema.d.ts +9 -11
  86. package/dist/types/Primitive/record/Types.d.ts +25 -25
  87. package/dist/types/Primitive/recursive/Fabricator.d.ts +16 -17
  88. package/dist/types/Primitive/recursive/Registry.d.ts +6 -7
  89. package/dist/types/Primitive/recursive/Schema.d.ts +8 -8
  90. package/dist/types/Primitive/recursive/Terminate.d.ts +13 -14
  91. package/dist/types/Primitive/recursive/Types.d.ts +31 -31
  92. package/dist/types/Primitive/recursive/self/Fabricator.d.ts +11 -12
  93. package/dist/types/Primitive/recursive/self/Schema.d.ts +10 -10
  94. package/dist/types/Primitive/recursive/self/Types.d.ts +7 -8
  95. package/dist/types/Primitive/string/Constants.d.ts +12 -13
  96. package/dist/types/Primitive/string/Fabricator.d.ts +2 -2
  97. package/dist/types/Primitive/string/Registry.d.ts +10 -16
  98. package/dist/types/Primitive/string/Schema.d.ts +5 -5
  99. package/dist/types/Primitive/string/Types.d.ts +17 -17
  100. package/dist/types/Primitive/symbol/Fabricator.d.ts +2 -2
  101. package/dist/types/Primitive/symbol/Registry.d.ts +4 -11
  102. package/dist/types/Primitive/symbol/Schema.d.ts +6 -6
  103. package/dist/types/Primitive/symbol/Types.d.ts +2 -2
  104. package/dist/types/Primitive/tuple/Fabricator.d.ts +7 -8
  105. package/dist/types/Primitive/tuple/Schema.d.ts +5 -5
  106. package/dist/types/Primitive/tuple/Types.d.ts +24 -25
  107. package/dist/types/Primitive/undefinable/Fabricator.d.ts +7 -7
  108. package/dist/types/Primitive/undefinable/Schema.d.ts +13 -13
  109. package/dist/types/Primitive/undefinable/Types.d.ts +10 -10
  110. package/dist/types/Primitive/undefined/Registry.d.ts +2 -2
  111. package/dist/types/Primitive/undefined/Schema.d.ts +4 -4
  112. package/dist/types/Primitive/undefined/Types.d.ts +3 -3
  113. package/dist/types/Random/CallSite.d.ts +63 -44
  114. package/dist/types/Random/Generator/sfc32.d.ts +4 -4
  115. package/dist/types/Random/Types.d.ts +214 -236
  116. package/dist/types/Random/index.d.ts +63 -70
  117. package/dist/types/Schema/Core.d.ts +19 -21
  118. package/dist/types/Schema/Registry.d.ts +3 -3
  119. package/dist/types/Schema/Types.d.ts +41 -48
  120. package/dist/types/Types.d.ts +39 -45
  121. package/dist/types/Utility/Core.d.ts +18 -9
  122. package/dist/types/index.d.ts +110 -108
  123. package/dist/types/internal.d.ts +68 -37
  124. package/package.json +17 -5
@@ -1,7 +1,7 @@
1
1
  import { Layer } from "../Types";
2
2
  /**
3
- * A zero-argument function that produces a float in `[0, 1)`, exactly
4
- * like `Math.random()` does.
3
+ * A zero-argument function that produces a float in `[0, 1)`, exactly like
4
+ * `Math.random()` does.
5
5
  */
6
6
  export type NumberGenerator = () => number;
7
7
  /**
@@ -14,7 +14,7 @@ export type Stream = {
14
14
  */
15
15
  readonly seed: string;
16
16
  /**
17
- * The count of times a number has been requested from this stream.
17
+ * The count of times a number has been requested from this stream.
18
18
  */
19
19
  readonly iterations: number;
20
20
  };
@@ -25,48 +25,47 @@ export type Stream = {
25
25
  */
26
26
  export type Algorithm = (seed: string) => NumberGenerator;
27
27
  /**
28
- * Everything a single leaf's randomness is derived from. Encoded as a
29
- * fixed tuple (`Random/index.ts`'s `encode`), this *is* the stream seed:
30
- * `toStream(algorithm, encode(trace)).seed === stream.seed` for every
31
- * traced leaf, so the derived seed is not a field of its own.
28
+ * Everything a single leaf's randomness is derived from. Encoded as a fixed
29
+ * tuple (`Random/index.ts`'s `encode`), this _is_ the stream seed:
30
+ * `toStream(algorithm, encode(trace)).seed === stream.seed` for every traced
31
+ * leaf, so the derived seed is not a field of its own.
32
32
  *
33
- * Attached to every built Fabricator as `.trace` — recording is
34
- * unconditional, even for a node that never draws (a bare `object`,
35
- * `always`, `object.compute`). Minting a stream from it
36
- * (`toStreamFromTrace`) is still paid only by nodes that draw.
33
+ * Attached to every built Fabricator as `.trace` — recording is unconditional,
34
+ * even for a node that never draws (a bare `object`, `always`,
35
+ * `object.compute`). Minting a stream from it (`toStreamFromTrace`) is still
36
+ * paid only by nodes that draw.
37
37
  *
38
38
  * Slots, in encoded order:
39
39
  *
40
- * - `seed` — the *instance's* seed, normalized to its parts
40
+ * - `seed` — the _instance's_ seed, normalized to its parts
41
41
  * ({@link RandomSource.seed}), not anything derived per leaf.
42
42
  * - `clock` — this construction's resolved "now," epoch milliseconds
43
- * (`Instance/Types.ts`'s `Config.clock`). Second, not after the
44
- * per-leaf slots: blast radius matches `seed` — both are instance-level
45
- * and perturb every leaf, unlike `file`/`path`/`kind`/`ordinal`, which
46
- * narrow to one leaf. Never `undefined` (unlike `file`/`ordinal`):
47
- * clock is always a concrete instant before any leaf dispatches
48
- * (`RandomSource`'s `Options.clock`).
49
- * - `root` — how `file` and `ordinal` were resolved ({@link RootKind}).
50
- * Sits immediately before `file` because that is what it explains.
51
- * Distinguishes the three situations that all produce `file:
52
- * undefined` (`{ kind: "none" }` attributed, an unattributed seeded
53
- * construction, a counted recursive expansion), so a captured trace
54
- * can be replayed faithfully via `new Fabricator(schema, trace)`.
55
- * - `file` — the file this node's *construction* (not the node) was
56
- * attributed to, relative to the instance's {@link Attribution} root
57
- * (absolute only if outside that root). `undefined` under
58
- * `"counted"` / `"unattributed"`, or `"attributed"` with
59
- * `{ kind: "none" }` — {@link RootKind} says which.
60
- * - `path` structural position within the construction: field name,
61
- * tuple slot, choice option, one segment per nesting level
62
- * (`Constructor.ts`'s `make`). Distinguishes two leaves of the same
63
- * kind in one construction. Stable under insert/remove/reorder of
64
- * unrelated siblingsonly a leaf's own position identifies it.
65
- * - `kind` schema kind the node was constructed as. Redundant given a
66
- * unique `path`, but changing a field's kind must change its data.
67
- * - `ordinal` which construction among those sharing this `file` this
68
- * node belongs to. `undefined` for `"unattributed"`, already unique
69
- * by its forked seed.
43
+ * (`Instance/Types.ts`'s `Config.clock`). Second, not after the per-leaf
44
+ * slots: blast radius matches `seed` — both are instance-level and perturb
45
+ * every leaf, unlike `file`/`path`/`kind`/`ordinal`, which narrow to one
46
+ * leaf. Never `undefined` (unlike `file`/`ordinal`): clock is always a
47
+ * concrete instant before any leaf dispatches (`RandomSource`'s
48
+ * `Options.clock`).
49
+ * - `root` — how `file` and `ordinal` were resolved ({@link RootKind}). Sits
50
+ * immediately before `file` because that is what it explains. Distinguishes
51
+ * the three situations that all produce `file: undefined` (`{ kind: "none" }`
52
+ * attributed, an unattributed seeded construction, a counted recursive
53
+ * expansion), so a captured trace can be replayed faithfully via `new
54
+ * Fabricator(schema, trace)`.
55
+ * - `file` — the file this node's _construction_ (not the node) was attributed
56
+ * to, relative to the instance's {@link Attribution} root (absolute only if
57
+ * outside that root). `undefined` under `"counted"` / `"unattributed"`, or
58
+ * `"attributed"` with `{ kind: "none" }` — {@link RootKind} says which.
59
+ * - `path`structural position within the construction: field name, tuple slot,
60
+ * choice option, one segment per nesting level (`Constructor.ts`'s `make`).
61
+ * Distinguishes two leaves of the same kind in one construction. Stable under
62
+ * insert/remove/reorder of unrelated siblings only a leaf's own position
63
+ * identifies it.
64
+ * - `kind` schema kind the node was constructed as. Redundant given a unique
65
+ * `path`, but changing a field's kind must change its data.
66
+ * - `ordinal` which construction among those sharing this `file` this node
67
+ * belongs to. `undefined` for `"unattributed"`, already unique by its forked
68
+ * seed.
70
69
  */
71
70
  export type Trace = {
72
71
  readonly seed: ReadonlyArray<string>;
@@ -78,15 +77,14 @@ export type Trace = {
78
77
  readonly ordinal: number | undefined;
79
78
  };
80
79
  /**
81
- * Caller-supplied overrides for the construction-owned {@link Trace}
82
- * slots {@link RandomSource.toRoot} resolves. `seed` is not among
83
- * them: it is the {@link RandomSource}'s own identity (forked via
84
- * {@link ConstructorOptions.seed} when replaying), not something
85
- * `toRoot` substitutes. `path`/`kind` are per-node and applied in
86
- * `construct()`, not here.
80
+ * Caller-supplied overrides for the construction-owned {@link Trace} slots
81
+ * {@link RandomSource.toRoot} resolves. `seed` is not among them: it is the
82
+ * {@link RandomSource}'s own identity (forked via {@link ConstructorOptions.seed}
83
+ * when replaying), not something `toRoot` substitutes. `path`/`kind` are
84
+ * per-node and applied in `construct()`, not here.
87
85
  *
88
- * Definedness, not `in`: `root` is present exactly when a trace is
89
- * being replayed and is never `undefined` on a real {@link Trace}.
86
+ * Definedness, not `in`: `root` is present exactly when a trace is being
87
+ * replayed and is never `undefined` on a real {@link Trace}.
90
88
  */
91
89
  export type RootPins = {
92
90
  clock?: number | undefined;
@@ -95,149 +93,141 @@ export type RootPins = {
95
93
  ordinal?: number | undefined;
96
94
  };
97
95
  /**
98
- * A construction's root: every {@link Trace} slot a {@link RootKind}
99
- * resolution fixes, before a leaf supplies its own `path`/`kind`.
100
- * `RandomSource.toRoot` resolves this once per construction; callers
101
- * spread it into a full {@link Trace} per leaf and hand that to
102
- * `toStreamFromTrace`. One stack walk, one construction-ordinal
103
- * bump — reused across every leaf that construction dispatches.
96
+ * A construction's root: every {@link Trace} slot a {@link RootKind} resolution
97
+ * fixes, before a leaf supplies its own `path`/`kind`. `RandomSource.toRoot`
98
+ * resolves this once per construction; callers spread it into a full
99
+ * {@link Trace} per leaf and hand that to `toStreamFromTrace`. One stack walk,
100
+ * one construction-ordinal bump reused across every leaf that construction
101
+ * dispatches.
104
102
  */
105
103
  export type ConstructionTrace = Omit<Trace, "path" | "kind">;
106
104
  /**
107
- * What a producer is told about the fabrication it is running inside.
108
- * One object, not a positional list: this is the only channel a producer
109
- * has, and a future addition must not change every kind's `.as(...)`
110
- * arity. Curated, not the whole instance `Config` — a producer has no
111
- * business reading `seed` or `attribution`, and `random` already carries
112
- * this leaf's own derived seed.
105
+ * What a producer is told about the fabrication it is running inside. One
106
+ * object, not a positional list: this is the only channel a producer has, and a
107
+ * future addition must not change every kind's `.as(...)` arity. Curated, not
108
+ * the whole instance `Config` — a producer has no business reading `seed` or
109
+ * `attribution`, and `random` already carries this leaf's own derived seed.
113
110
  */
114
111
  export type ProduceContext = {
115
112
  /** This leaf's own seeded stream, keyed by its structural path. */
116
113
  random: Stream;
117
114
  /**
118
- * This construction's resolved "now," epoch milliseconds — the active
119
- * `wrap` frame's `Config.clock` if one is active, else the instance's
120
- * (`Instance/Types.ts`'s `Config.clock`). Defaults to an instant derived
121
- * from the instance's seed, not `Date.now()`, so a producer that reads
122
- * it replays like one that only reads `random`. A number, not a `Date`:
123
- * the instant is fixed once resolved, and a `Date` handed to every
124
- * producer would be a shared mutable — the same footgun `T.always([])`
125
- * sharing one array reference already warns against.
115
+ * This construction's resolved "now," epoch milliseconds — the active `wrap`
116
+ * frame's `Config.clock` if one is active, else the instance's
117
+ * (`Instance/Types.ts`'s `Config.clock`). Defaults to an instant derived from
118
+ * the instance's seed, not `Date.now()`, so a producer that reads it replays
119
+ * like one that only reads `random`. A number, not a `Date`: the instant is
120
+ * fixed once resolved, and a `Date` handed to every producer would be a
121
+ * shared mutable — the same footgun `T.always([])` sharing one array
122
+ * reference already warns against.
126
123
  */
127
124
  clock: number;
128
125
  };
129
126
  /**
130
127
  * A kind's opaque custom producer — `.as(produce)` — given a
131
- * {@link ProduceContext} so its output replays under a seed like every
132
- * other primitive's draws. A zero-argument function (`() => $T`) is
133
- * still assignable, so every existing `.as(() => ...)` call compiles.
128
+ * {@link ProduceContext} so its output replays under a seed like every other
129
+ * primitive's draws. A zero-argument function (`() => $T`) is still assignable,
130
+ * so every existing `.as(() => ...)` call compiles.
134
131
  */
135
132
  export type Produce<$T> = (context: ProduceContext) => $T;
136
133
  /**
137
- * How one *construction* (a single `new Fabricator(...)` call) is rooted,
138
- * before any of its leaves are dispatched — resolved once, not per leaf,
139
- * at `Constructor.ts`'s `construct()`. Every leaf then derives its stream
140
- * from this root plus its own structural path, so inserting or reordering
141
- * a sibling field can never shift another field onto a different stream.
134
+ * How one _construction_ (a single `new Fabricator(...)` call) is rooted,
135
+ * before any of its leaves are dispatched — resolved once, not per leaf, at
136
+ * `Constructor.ts`'s `construct()`. Every leaf then derives its stream from
137
+ * this root plus its own structural path, so inserting or reordering a sibling
138
+ * field can never shift another field onto a different stream.
142
139
  *
143
- * Each variant is a decision about the two {@link Trace} slots a
144
- * construction owns — `file` and `ordinal` — and nothing else:
140
+ * Each variant is a decision about the two {@link Trace} slots a construction
141
+ * owns — `file` and `ordinal` — and nothing else:
145
142
  *
146
- * | variant | `file` | `ordinal` |
147
- * | ----------------- | -------------------------- | ---------------------- |
148
- * | `"attributed"` | resolved from the stack | next ordinal for it |
149
- * | `"counted"` | `undefined` | next file-less ordinal |
150
- * | `"unattributed"` | `undefined` | `undefined` |
143
+ * | variant | `file` | `ordinal` |
144
+ * | ---------------- | ----------------------- | ---------------------- |
145
+ * | `"attributed"` | resolved from the stack | next ordinal for it |
146
+ * | `"counted"` | `undefined` | next file-less ordinal |
147
+ * | `"unattributed"` | `undefined` | `undefined` |
151
148
  *
152
- * `"attributed"` walks the live call stack once (`resolveCallerFile()`)
153
- * and relativizes it under the instance's `Attribution` root — or, under
154
- * `{ kind: "none" }`, resolves no file — then assigns the next ordinal
155
- * for that file. Two constructions in the same file diverge by default;
156
- * a lone construction stays reproducible across however many times its
157
- * file is imported or re-run. `ConstructorOptions.file` without `root`
158
- * pins that file and draws the next ordinal for it (the wrapping-
159
- * integration case). A replay (`pins.root` given) takes `file` and
160
- * `ordinal` verbatim, including `undefined`.
161
- * `test/fixtures/checkout-a`/`checkout-b` stand in for two checkouts
162
- * using real frames instead.
149
+ * `"attributed"` walks the live call stack once (`resolveCallerFile()`) and
150
+ * relativizes it under the instance's `Attribution` root — or, under `{ kind:
151
+ * "none" }`, resolves no file — then assigns the next ordinal for that file.
152
+ * Two constructions in the same file diverge by default; a lone construction
153
+ * stays reproducible across however many times its file is imported or re-run.
154
+ * `ConstructorOptions.file` without `root` pins that file and draws the next
155
+ * ordinal for it (the wrapping- integration case). A replay (`pins.root` given)
156
+ * takes `file` and `ordinal` verbatim, including `undefined`.
157
+ * `test/fixtures/checkout-a`/`checkout-b` stand in for two checkouts using real
158
+ * frames instead.
163
159
  *
164
160
  * `"counted"` indexes without attributing. Under `{ kind: "none" }` an
165
- * `"attributed"` scope resolves to precisely this, and the two share
166
- * the one file-less bucket — reachable only if both kinds of scope were
167
- * opened on a single source, which nothing does. `"counted"` is not a
168
- * variant you choose when building — it is recorded on a node's
169
- * {@link Trace} (and replayed) for expansions inside `T.recursive`,
170
- * whose private fork uses it so each lazy expansion gets an ordinal
171
- * (see `recursive/Fabricator.ts`). An identity that isn't a stack frame
172
- * but should still vary with the instance's seed is
161
+ * `"attributed"` scope resolves to precisely this, and the two share the one
162
+ * file-less bucket — reachable only if both kinds of scope were opened on a
163
+ * single source, which nothing does. `"counted"` is not a variant you choose
164
+ * when building — it is recorded on a node's {@link Trace} (and replayed) for
165
+ * expansions inside `T.recursive`, whose private fork uses it so each lazy
166
+ * expansion gets an ordinal (see `recursive/Fabricator.ts`). An identity that
167
+ * isn't a stack frame but should still vary with the instance's seed is
173
168
  * `ConstructorOptions.seed`'s layered form (`{@link Layered}`, via
174
169
  * `layer(...)`) — see `ConstructorOptions`.
175
170
  *
176
- * `"unattributed"` fixes neither slot — used only by a source already
177
- * isolated for one construction (an explicitly seeded
178
- * `new Fabricator(schema, { seed })`, which forks a new `RandomSource`
179
- * for that one build). A layered seed (`{@link Layered}`, via
180
- * `layer(...)`) still opens this same scope: composing onto a base seed
181
- * is a statement about *what* the fork's seed is, not how the fork
182
- * itself should be rooted.
171
+ * `"unattributed"` fixes neither slot — used only by a source already isolated
172
+ * for one construction (an explicitly seeded `new Fabricator(schema, { seed
173
+ * })`, which forks a new `RandomSource` for that one build). A layered seed
174
+ * (`{@link Layered}`, via `layer(...)`) still opens this same scope: composing
175
+ * onto a base seed is a statement about _what_ the fork's seed is, not how the
176
+ * fork itself should be rooted.
183
177
  *
184
- * A plain string union, not a discriminant object: none of the three
185
- * variants carries data of its own. Caller-supplied overrides go
186
- * through {@link RootPins} on {@link RandomSource.toRoot}, not through
187
- * this union. A `{ kind: RootKind }` wrapper would invite a field an
188
- * object shape can carry and a switch can silently ignore.
178
+ * A plain string union, not a discriminant object: none of the three variants
179
+ * carries data of its own. Caller-supplied overrides go through
180
+ * {@link RootPins} on {@link RandomSource.toRoot}, not through this union. A `{
181
+ * kind: RootKind }` wrapper would invite a field an object shape can carry and
182
+ * a switch can silently ignore.
189
183
  */
190
184
  export type RootKind = "attributed" | "counted" | "unattributed";
191
185
  /**
192
- * A seed as a caller supplies it: one string, or several — several lets
193
- * a caller compose independent parts (user id, session id, scenario
194
- * label) without joining them first. Always normalized internally to
195
- * `ReadonlyArray<string>` (`toRandomSource`'s `normalizeSeed`); a single
196
- * string is the one-element case.
186
+ * A seed as a caller supplies it: one string, or several — several lets a
187
+ * caller compose independent parts (user id, session id, scenario label)
188
+ * without joining them first. Always normalized internally to
189
+ * `ReadonlyArray<string>` (`toRandomSource`'s `normalizeSeed`); a single string
190
+ * is the one-element case.
197
191
  */
198
192
  export type Seed = string | ReadonlyArray<string>;
199
193
  /**
200
- * A {@link Seed} tagged as composing onto whatever base is in effect,
201
- * rather than replacing it — what `layer(seed)` (`Random/index.ts`)
202
- * produces. Tagged with `[Layer]` exactly as `replace()`
203
- * (`Utility/Core.ts`) tags a merge operand with `[Replace]`, so a
204
- * caller never names the symbol and no ordinary `Seed` string or
205
- * array — can be mistaken for one.
194
+ * A {@link Seed} tagged as composing onto whatever base is in effect, rather
195
+ * than replacing it — what `layer(seed)` (`Random/index.ts`) produces. Tagged
196
+ * with `[Layer]` exactly as `replace()` (`Utility/Core.ts`) tags a merge
197
+ * operand with `[Replace]`, so a caller never names the symbol and no ordinary
198
+ * `Seed` string or array can be mistaken for one.
206
199
  */
207
200
  export type Layered = {
208
201
  readonly [Layer]: Seed;
209
202
  };
210
203
  /**
211
- * How an instance normalizes a construction's resolved file before it
212
- * becomes part of that construction's root — set once via
213
- * `initialize({ attribution })`.
204
+ * How an instance normalizes a construction's resolved file before it becomes
205
+ * part of that construction's root — set once via `initialize({ attribution
206
+ * })`.
214
207
  *
215
- * `"rooted"` expresses every file relative to `root`, so a checkout at
216
- * a different absolute path on a different machine derives the same
217
- * seeds. `root` accepts an absolute path or a `file://` URL (e.g.
218
- * `new URL("..", import.meta.url).href`, which needs no `node:path`),
219
- * and is a normalization parameter only — it never enters the hashed
220
- * material, so moving the root without moving the files under it
221
- * changes nothing. A file outside `root` is expressed with a leading
222
- * `..` run rather than left absolute, so it stays stable too, as long
223
- * as both locations move together under the same checkout (see
224
- * `relativize`, `Random/CallSite.ts`).
208
+ * `"rooted"` expresses every file relative to `root`, so a checkout at a
209
+ * different absolute path on a different machine derives the same seeds. `root`
210
+ * accepts an absolute path or a `file://` URL (e.g. `new URL("..",
211
+ * import.meta.url).href`, which needs no `node:path`), and is a normalization
212
+ * parameter only — it never enters the hashed material, so moving the root
213
+ * without moving the files under it changes nothing. A file outside `root` is
214
+ * expressed with a leading `..` run rather than left absolute, so it stays
215
+ * stable too, as long as both locations move together under the same checkout
216
+ * (see `relativize`, `Random/CallSite.ts`).
225
217
  *
226
- * `"call site"`, the default, is `"rooted"` at the directory of
227
- * whichever file called `initialize()` — resolved once, at that call,
228
- * from the live stack. Two `initialize()` calls in different files that
229
- * share a seed and happen to produce the same file's-worth of relative
230
- * paths (a symmetric monorepo layout — this repo's `pkg/fabricator` and
231
- * `pkg/fabricator-adapter-typebox-v0` test suites) will collide; use
232
- * `"rooted"` at a shared repository root instead.
218
+ * `"call site"`, the default, is `"rooted"` at the directory of whichever file
219
+ * called `initialize()` — resolved once, at that call, from the live stack. Two
220
+ * `initialize()` calls in different files that share a seed and happen to
221
+ * produce the same file's-worth of relative paths (a symmetric monorepo layout
222
+ * — this repo's `pkg/fabricator` and `pkg/fabricator-adapter-typebox-v0` test
223
+ * suites) will collide; use `"rooted"` at a shared repository root instead.
233
224
  *
234
- * `"none"` attributes nothing: every construction in the instance draws
235
- * its root from one shared, file-less counter. Maximally portable — no
236
- * path can influence a seed — at the cost of every construction sharing
237
- * one counter, so adding, removing, or reordering a *construction*
238
- * anywhere in the instance shifts every later one. Individual fields
239
- * within one construction are unaffected: they're keyed by structural
240
- * path, not dispatch order.
225
+ * `"none"` attributes nothing: every construction in the instance draws its
226
+ * root from one shared, file-less counter. Maximally portable — no path can
227
+ * influence a seed — at the cost of every construction sharing one counter, so
228
+ * adding, removing, or reordering a _construction_ anywhere in the instance
229
+ * shifts every later one. Individual fields within one construction are
230
+ * unaffected: they're keyed by structural path, not dispatch order.
241
231
  */
242
232
  export type Attribution = {
243
233
  kind: "rooted";
@@ -248,14 +238,13 @@ export type Attribution = {
248
238
  kind: "none";
249
239
  };
250
240
  /**
251
- * {@link Attribution} after `"call site"` has been resolved against the
252
- * live stack and `root` normalized — what actually drives
253
- * construction-root resolution. This, not the caller-facing
254
- * `Attribution`, is what `RandomSource.fork` threads through:
255
- * re-resolving `"call site"` inside a fork would read the stack at
256
- * whatever moment the fork happens to run (an explicitly seeded build,
257
- * an enumeration's rebuild) and root the child somewhere unrelated to
258
- * the instance that spawned it.
241
+ * {@link Attribution} after `"call site"` has been resolved against the live
242
+ * stack and `root` normalized — what actually drives construction-root
243
+ * resolution. This, not the caller-facing `Attribution`, is what
244
+ * `RandomSource.fork` threads through: re-resolving `"call site"` inside a fork
245
+ * would read the stack at whatever moment the fork happens to run (an
246
+ * explicitly seeded build, an enumeration's rebuild) and root the child
247
+ * somewhere unrelated to the instance that spawned it.
259
248
  */
260
249
  export type ResolvedAttribution = {
261
250
  kind: "rooted";
@@ -264,12 +253,11 @@ export type ResolvedAttribution = {
264
253
  kind: "none";
265
254
  };
266
255
  /**
267
- * `clock` is required, unlike `seed`/`algorithm`/`attribution` — by the
268
- * time a `RandomSource` is built, both the wall-clock default and the
269
- * `"seeded"` policy (`Instance/Types.ts`'s `Config.clock`) have already
270
- * been resolved to a concrete epoch-millisecond instant
271
- * (`Instance/Core.ts`'s `resolveClock`), so `toRandomSource` has no
272
- * default left to supply.
256
+ * `clock` is required, unlike `seed`/`algorithm`/`attribution` — by the time a
257
+ * `RandomSource` is built, both the wall-clock default and the `"seeded"`
258
+ * policy (`Instance/Types.ts`'s `Config.clock`) have already been resolved to a
259
+ * concrete epoch-millisecond instant (`Instance/Core.ts`'s `resolveClock`), so
260
+ * `toRandomSource` has no default left to supply.
273
261
  */
274
262
  export type Options = {
275
263
  seed?: Seed | undefined;
@@ -278,51 +266,46 @@ export type Options = {
278
266
  clock: number;
279
267
  };
280
268
  /**
281
- * `new Fabricator(schema, options)`'s own option shape — not
282
- * `Options`. {@link Trace} is assignable to this (every slot optional
283
- * here, required there, and `file`/`ordinal` are `T | undefined` on
284
- * both so `{ ...trace }` typechecks under
285
- * `exactOptionalPropertyTypes`), which is what makes
286
- * `new Fabricator(schema, trace)` a legal replay.
269
+ * `new Fabricator(schema, options)`'s own option shape — not `Options`.
270
+ * {@link Trace} is assignable to this (every slot optional here, required
271
+ * there, and `file`/`ordinal` are `T | undefined` on both so `{ ...trace }`
272
+ * typechecks under `exactOptionalPropertyTypes`), which is what makes `new
273
+ * Fabricator(schema, trace)` a legal replay.
287
274
  *
288
- * A bare `seed` is a statement about *attribution*: it forks an
289
- * isolated `RandomSource` from exactly that value, sidestepping both
290
- * the default call-site logic and the instance's own seed. The same
291
- * seed reproduces the same result regardless of which file it's
292
- * constructed from, which instance built it, or how that instance was
293
- * itself seeded useful for a fixture that should never change no
294
- * matter how the surrounding run is reseeded.
275
+ * A bare `seed` is a statement about _attribution_: it forks an isolated
276
+ * `RandomSource` from exactly that value, sidestepping both the default
277
+ * call-site logic and the instance's own seed. The same seed reproduces the
278
+ * same result regardless of which file it's constructed from, which instance
279
+ * built it, or how that instance was itself seeded — useful for a fixture that
280
+ * should never change no matter how the surrounding run is reseeded.
295
281
  *
296
- * `seed: layer(...)` (via `layer()`, `Random/index.ts`) is the same
297
- * fork, but composed onto the instance's own seed
298
- * (`[...instance.seed, ...seed]`) instead of replacing it — the
299
- * construction still varies when the instance is reseeded, which the
300
- * bare form does not (see {@link RootKind}'s `"counted"` paragraph).
301
- * This is `fork`/`wrap`'s own `Overlay.seed` mechanism one level down:
302
- * the instance itself is the base, so no separate instance is needed
303
- * just to pin an identity that should still track the instance's seed.
282
+ * `seed: layer(...)` (via `layer()`, `Random/index.ts`) is the same fork, but
283
+ * composed onto the instance's own seed (`[...instance.seed, ...seed]`) instead
284
+ * of replacing it — the construction still varies when the instance is
285
+ * reseeded, which the bare form does not (see {@link RootKind}'s `"counted"`
286
+ * paragraph). This is `fork`/`wrap`'s own `Overlay.seed` mechanism one level
287
+ * down: the instance itself is the base, so no separate instance is needed just
288
+ * to pin an identity that should still track the instance's seed.
304
289
  *
305
290
  * `clock` / `root` / `file` / `ordinal` pin the construction-owned
306
- * {@link Trace} slots {@link RandomSource.toRoot} would otherwise
307
- * resolve. Definedness, not `in`: `root` given means this is a replay
308
- * (`file` and `ordinal` taken verbatim, `undefined` included, no
309
- * stack walk and no counter bump). `root` absent but `file` given pins
310
- * that file and draws `ordinal` from *that file's* counter — the
311
- * wrapping-integration case. Neither given resolves as an ordinary
312
- * construction. A seeded construction is not, by default, asking for a
313
- * different "now"; a replayed trace whose `clock` is present explicitly
291
+ * {@link Trace} slots {@link RandomSource.toRoot} would otherwise resolve.
292
+ * Definedness, not `in`: `root` given means this is a replay (`file` and
293
+ * `ordinal` taken verbatim, `undefined` included, no stack walk and no counter
294
+ * bump). `root` absent but `file` given pins that file and draws `ordinal` from
295
+ * _that file's_ counter the wrapping-integration case. Neither given resolves
296
+ * as an ordinary construction. A seeded construction is not, by default, asking
297
+ * for a different "now"; a replayed trace whose `clock` is present explicitly
314
298
  * is.
315
299
  *
316
- * `path` is the base structural path `make` extends for descendants,
317
- * so replaying a nested node's trace reproduces its subtree at the
318
- * positions it originally occupied. `kind`, when a string, must match
319
- * `schema`'s own `[Kind]` or `construct()` throws
320
- * `TraceKindMismatchError`.
300
+ * `path` is the base structural path `make` extends for descendants, so
301
+ * replaying a nested node's trace reproduces its subtree at the positions it
302
+ * originally occupied. `kind`, when a string, must match `schema`'s own
303
+ * `[Kind]` or `construct()` throws `TraceKindMismatchError`.
321
304
  *
322
- * No per-build algorithm override: it complicates root resolution for
323
- * a capability nobody asked for, unlike `seed`, which is a real
324
- * statement about attribution. Only `initialize({ seed, algorithm })`
325
- * — instance-wide, via `Options` — sets the algorithm.
305
+ * No per-build algorithm override: it complicates root resolution for a
306
+ * capability nobody asked for, unlike `seed`, which is a real statement about
307
+ * attribution. Only `initialize({ seed, algorithm })` — instance-wide, via
308
+ * `Options` — sets the algorithm.
326
309
  */
327
310
  export type ConstructorOptions = {
328
311
  seed?: Seed | Layered | undefined;
@@ -334,51 +317,46 @@ export type ConstructorOptions = {
334
317
  ordinal?: number | undefined;
335
318
  };
336
319
  /**
337
- * An isolated source of randomness: everything a single `initialize()`
338
- * instance needs to derive private, reproducible seeds for the
339
- * fabricators it builds. Each instance owns its own seed, builder, and
340
- * per-construction counters — nothing here is shared module-level
341
- * state, so independently initialized instances (e.g. parallel tests)
342
- * can never perturb each other.
320
+ * An isolated source of randomness: everything a single `initialize()` instance
321
+ * needs to derive private, reproducible seeds for the fabricators it builds.
322
+ * Each instance owns its own seed, builder, and per-construction counters —
323
+ * nothing here is shared module-level state, so independently initialized
324
+ * instances (e.g. parallel tests) can never perturb each other.
343
325
  */
344
326
  export type RandomSource = {
345
327
  /**
346
- * Resolve one construction's root — see {@link RootKind}. Called once
347
- * per `new Fabricator(...)` (or per lazy expansion of a `T.recursive`
348
- * schema, each of which resolves its own root on a private forked
349
- * source), never per leaf: the returned {@link ConstructionTrace} is
350
- * what every leaf beneath it completes into a full {@link Trace} and
351
- * hands to `toStreamFromTrace`. One stack walk and
352
- * construction-ordinal bump serves the whole construction.
328
+ * Resolve one construction's root — see {@link RootKind}. Called once per `new
329
+ * Fabricator(...)` (or per lazy expansion of a `T.recursive` schema, each of
330
+ * which resolves its own root on a private forked source), never per leaf:
331
+ * the returned {@link ConstructionTrace} is what every leaf beneath it
332
+ * completes into a full {@link Trace} and hands to `toStreamFromTrace`. One
333
+ * stack walk and construction-ordinal bump serves the whole construction.
353
334
  */
354
335
  toRoot(kind: RootKind, pins?: RootPins): ConstructionTrace;
355
336
  /**
356
- * The algorithm this source (and every fork of it) hashes with.
357
- * Stream derivation is *not* a member: it depends on no per-source
358
- * state, so it is the free function `toStreamFromTrace(algorithm,
359
- * trace)`. `toRoot` is the only stateful member (per-file ordinal
360
- * counters).
337
+ * The algorithm this source (and every fork of it) hashes with. Stream
338
+ * derivation is _not_ a member: it depends on no per-source state, so it is
339
+ * the free function `toStreamFromTrace(algorithm, trace)`. `toRoot` is the
340
+ * only stateful member (per-file ordinal counters).
361
341
  */
362
342
  readonly algorithm: Algorithm;
363
343
  /**
364
- * The seed this instance currently derives every stream from,
365
- * normalized to its parts — a single string becomes a one-element
366
- * array. Always an array so a caller reading it back (e.g.
367
- * `initialize({ seed: instance.seed })`) round-trips through the same
368
- * `Seed`-accepting surface it came from.
344
+ * The seed this instance currently derives every stream from, normalized to
345
+ * its parts — a single string becomes a one-element array. Always an array so
346
+ * a caller reading it back (e.g. `initialize({ seed: instance.seed })`)
347
+ * round-trips through the same `Seed`-accepting surface it came from.
369
348
  */
370
349
  readonly seed: ReadonlyArray<string>;
371
350
  /**
372
- * Create a new, fully isolated `RandomSource` — its own private
373
- * per-file construction counters, sharing only the algorithm — seeded
374
- * independently from this one. For a build whose randomness must stay
375
- * entirely self-contained (an explicitly seeded
376
- * `new Fabricator(schema, { seed })`, or `T.recursive`, whose expansion
377
- * count is data-dependent, unlike every other kind's fixed,
378
- * schema-determined dispatch count): forking means its internal draws
379
- * can never perturb, or be perturbed by, anything else built from the
380
- * same `initialize()` instance, no matter how many times or how deeply
381
- * it expands.
351
+ * Create a new, fully isolated `RandomSource` — its own private per-file
352
+ * construction counters, sharing only the algorithm — seeded independently
353
+ * from this one. For a build whose randomness must stay entirely
354
+ * self-contained (an explicitly seeded `new Fabricator(schema, { seed })`, or
355
+ * `T.recursive`, whose expansion count is data-dependent, unlike every other
356
+ * kind's fixed, schema-determined dispatch count): forking means its internal
357
+ * draws can never perturb, or be perturbed by, anything else built from the
358
+ * same `initialize()` instance, no matter how many times or how deeply it
359
+ * expands.
382
360
  */
383
361
  fork(seed: Seed): RandomSource;
384
362
  };