@typeonce/effect-machine 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +4 -3
  2. package/dist/Machine.d.ts +24 -6
  3. package/dist/Machine.d.ts.map +1 -1
  4. package/dist/Machine.js.map +1 -1
  5. package/dist/internal/machine/atom.d.ts +5 -0
  6. package/dist/internal/machine/atom.d.ts.map +1 -1
  7. package/dist/internal/machine/atom.js +6 -3
  8. package/dist/internal/machine/atom.js.map +1 -1
  9. package/dist/internal/machine/machine.d.ts.map +1 -1
  10. package/dist/internal/machine/machine.js +1 -1
  11. package/dist/internal/machine/machine.js.map +1 -1
  12. package/dist/unstable/reactivity/AtomMachine.d.ts +26 -0
  13. package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
  14. package/dist/unstable/reactivity/AtomMachine.js +23 -0
  15. package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
  16. package/docs/agent-guide.md +14 -0
  17. package/package.json +5 -5
  18. package/src/Machine.ts +6909 -0
  19. package/src/index.ts +1 -0
  20. package/src/internal/machine/activities.ts +108 -0
  21. package/src/internal/machine/atom.ts +684 -0
  22. package/src/internal/machine/cluster.ts +394 -0
  23. package/src/internal/machine/command.ts +58 -0
  24. package/src/internal/machine/commandRuntime.ts +43 -0
  25. package/src/internal/machine/configuration.ts +1331 -0
  26. package/src/internal/machine/errors.ts +87 -0
  27. package/src/internal/machine/executionPlan.ts +996 -0
  28. package/src/internal/machine/invocation.ts +119 -0
  29. package/src/internal/machine/machine.ts +1750 -0
  30. package/src/internal/machine/planner.ts +1933 -0
  31. package/src/internal/machine/process.ts +906 -0
  32. package/src/internal/machine/protocol.ts +322 -0
  33. package/src/internal/machine/readiness.ts +10 -0
  34. package/src/internal/machine/runtime.ts +2512 -0
  35. package/src/internal/machine/serialization.ts +498 -0
  36. package/src/internal/machine/stateDefinition.ts +270 -0
  37. package/src/internal/machine/symbols.ts +2 -0
  38. package/src/internal/machine/topology.ts +479 -0
  39. package/src/internal/testing/machine/arbitrary.ts +102 -0
  40. package/src/internal/testing/machine/exploration.ts +331 -0
  41. package/src/internal/testing/machine/finiteModel.ts +1498 -0
  42. package/src/internal/testing/machine/invariant.ts +372 -0
  43. package/src/internal/testing/machine/probe.ts +79 -0
  44. package/src/internal/testing/machine/referenceModel.ts +1505 -0
  45. package/src/internal/testing/machine/runtime.ts +1710 -0
  46. package/src/internal/testing/machine/runtimeInvariant.ts +486 -0
  47. package/src/internal/testing/machine/trace.ts +150 -0
  48. package/src/internal/testing/machine/verification.ts +1890 -0
  49. package/src/testing/MachineTest.ts +2067 -0
  50. package/src/testing/index.ts +7 -0
  51. package/src/unstable/cluster/ClusterMachine.ts +390 -0
  52. package/src/unstable/cluster/index.ts +1 -0
  53. package/src/unstable/reactivity/AtomMachine.ts +696 -0
  54. package/src/unstable/reactivity/index.ts +1 -0
@@ -0,0 +1,479 @@
1
+ /**
2
+ * Internal machine topology and target helpers.
3
+ *
4
+ * @since 0.4.0
5
+ */
6
+
7
+ import * as Option from "effect/Option"
8
+ import { hasProperty } from "effect/Predicate"
9
+ import * as Schema from "effect/Schema"
10
+ import type { Machine } from "../../Machine.js"
11
+
12
+ export const TargetTypeId = "~effect/Machine/Target"
13
+
14
+ export const TargetSnapshotTypeId: unique symbol = Symbol("effect/Machine/TargetSnapshot")
15
+
16
+ export const StateInputTypeId: unique symbol = Symbol("effect/Machine/StateInput")
17
+
18
+ export const StateConstructionTypeId: unique symbol = Symbol("effect/Machine/StateConstruction")
19
+
20
+ export const HistoryTargetTypeId: unique symbol = Symbol("effect/Machine/HistoryTarget")
21
+
22
+ export const ChoiceTargetTypeId: unique symbol = Symbol("effect/Machine/ChoiceTarget")
23
+
24
+ interface StateInput {
25
+ readonly [StateInputTypeId]: typeof StateInputTypeId
26
+ readonly input: unknown
27
+ }
28
+
29
+ /** Internal target produced by the history target builder. History nodes are
30
+ * routing instructions and are never part of an active configuration. */
31
+ export interface HistoryTarget {
32
+ readonly [HistoryTargetTypeId]: typeof HistoryTargetTypeId
33
+ readonly path: string
34
+ readonly parent: string
35
+ }
36
+
37
+ /** Internal target produced by a choice target builder. */
38
+ export interface ChoiceTarget {
39
+ readonly [ChoiceTargetTypeId]: typeof ChoiceTargetTypeId
40
+ readonly path: string
41
+ readonly parent: string
42
+ readonly values?: Readonly<Record<string, unknown>>
43
+ }
44
+
45
+ export const makeHistoryTarget = (path: string, parent: string): HistoryTarget => ({
46
+ [HistoryTargetTypeId]: HistoryTargetTypeId,
47
+ path,
48
+ parent
49
+ })
50
+
51
+ export const isHistoryTarget = (u: unknown): u is HistoryTarget => hasProperty(u, HistoryTargetTypeId)
52
+
53
+ export const makeChoiceTarget = (
54
+ path: string,
55
+ parent: string,
56
+ values?: Readonly<Record<string, unknown>>
57
+ ): ChoiceTarget => ({
58
+ [ChoiceTargetTypeId]: ChoiceTargetTypeId,
59
+ path,
60
+ parent,
61
+ ...(values === undefined ? {} : { values })
62
+ })
63
+
64
+ export const isChoiceTarget = (u: unknown): u is ChoiceTarget => hasProperty(u, ChoiceTargetTypeId)
65
+
66
+ interface NormalizedStateNodeDefinitionBase {
67
+ readonly annotations: Readonly<Machine.StateNodeAnnotations> | undefined
68
+ }
69
+
70
+ type NormalizedStateNodeDefinition =
71
+ | (NormalizedStateNodeDefinitionBase & {
72
+ readonly type: "atomic"
73
+ readonly schema: Machine.TaggedSchema
74
+ readonly output: undefined
75
+ readonly history: undefined
76
+ readonly initial: undefined
77
+ readonly states: undefined
78
+ })
79
+ | (NormalizedStateNodeDefinitionBase & {
80
+ readonly type: "compound"
81
+ readonly schema: Machine.TaggedSchema
82
+ readonly output: undefined
83
+ readonly history: undefined
84
+ readonly initial: string
85
+ readonly states: Machine.StateTree
86
+ })
87
+ | (NormalizedStateNodeDefinitionBase & {
88
+ readonly type: "parallel"
89
+ readonly schema: Machine.TaggedSchema
90
+ readonly output: Schema.Top | undefined
91
+ readonly history: undefined
92
+ readonly initial: undefined
93
+ readonly states: Machine.StateTree
94
+ })
95
+ | (NormalizedStateNodeDefinitionBase & {
96
+ readonly type: "final"
97
+ readonly schema: Machine.TaggedSchema
98
+ readonly output: Schema.Top | undefined
99
+ readonly history: undefined
100
+ readonly initial: undefined
101
+ readonly states: undefined
102
+ })
103
+ | (NormalizedStateNodeDefinitionBase & {
104
+ readonly type: "history"
105
+ readonly schema: undefined
106
+ readonly output: undefined
107
+ readonly history: "shallow" | "deep"
108
+ readonly initial: undefined
109
+ readonly states: undefined
110
+ })
111
+ | (NormalizedStateNodeDefinitionBase & {
112
+ readonly type: "choice"
113
+ readonly schema: undefined
114
+ readonly output: undefined
115
+ readonly history: undefined
116
+ readonly initial: undefined
117
+ readonly states: undefined
118
+ })
119
+
120
+ export const getStateNodeDefinition = (
121
+ path: string,
122
+ definition: Machine.TaggedSchema | Machine.StateNodeConfig
123
+ ): NormalizedStateNodeDefinition => {
124
+ if (!Schema.isSchema(definition) && definition.type === "history") {
125
+ return {
126
+ schema: undefined,
127
+ output: undefined,
128
+ annotations: definition.annotations,
129
+ type: "history",
130
+ history: definition.history === "deep" ? "deep" : "shallow",
131
+ initial: undefined,
132
+ states: undefined
133
+ }
134
+ }
135
+ if (!Schema.isSchema(definition) && definition.type === "choice") {
136
+ return {
137
+ schema: undefined,
138
+ output: undefined,
139
+ annotations: definition.annotations,
140
+ type: "choice",
141
+ history: undefined,
142
+ initial: undefined,
143
+ states: undefined
144
+ }
145
+ }
146
+ if (Schema.isSchema(definition)) {
147
+ return {
148
+ schema: definition,
149
+ output: undefined,
150
+ annotations: Schema.resolveAnnotations(definition),
151
+ type: "atomic",
152
+ history: undefined,
153
+ initial: undefined,
154
+ states: undefined
155
+ }
156
+ }
157
+ if (!hasProperty(definition, "schema") || !Schema.isSchema(definition.schema)) {
158
+ throw new Error(`Machine.make expected state "${path}" to be a tagged schema or state node config`)
159
+ }
160
+ if (definition.type === "parallel" && !hasProperty(definition, "states")) {
161
+ throw new Error(`Machine.make expected parallel state "${path}" to declare child regions`)
162
+ }
163
+ if (hasProperty(definition, "states")) {
164
+ const type: unknown = definition.type
165
+ if (type === "final") {
166
+ throw new Error(`Machine.make expected compound state "${path}" to be active`)
167
+ }
168
+ if (definition.type === "parallel") {
169
+ return {
170
+ schema: definition.schema,
171
+ output: Schema.isSchema(definition.output) ? definition.output : undefined,
172
+ annotations: Schema.resolveAnnotations(definition.schema),
173
+ type: "parallel",
174
+ history: undefined,
175
+ initial: undefined,
176
+ states: definition.states
177
+ }
178
+ }
179
+ if (typeof definition.initial !== "string") {
180
+ throw new Error(`Machine.make expected compound state "${path}" to declare an initial child`)
181
+ }
182
+ return {
183
+ schema: definition.schema,
184
+ output: undefined,
185
+ annotations: Schema.resolveAnnotations(definition.schema),
186
+ type: "compound",
187
+ history: undefined,
188
+ initial: definition.initial,
189
+ states: definition.states
190
+ }
191
+ }
192
+ const output = Schema.isSchema(definition.output) ? definition.output : undefined
193
+ return definition.type === "final"
194
+ ? {
195
+ schema: definition.schema,
196
+ output,
197
+ annotations: Schema.resolveAnnotations(definition.schema),
198
+ type: "final",
199
+ history: undefined,
200
+ initial: undefined,
201
+ states: undefined
202
+ }
203
+ : {
204
+ schema: definition.schema,
205
+ output: undefined,
206
+ annotations: Schema.resolveAnnotations(definition.schema),
207
+ type: "atomic",
208
+ history: undefined,
209
+ initial: undefined,
210
+ states: undefined
211
+ }
212
+ }
213
+
214
+ export const compileStateNodes = (states: Machine.StateSchemas): Machine.StateNodes => {
215
+ const byPath = new Map<string, Machine.StateNode>()
216
+ let order = 0
217
+
218
+ const compile = (tree: Machine.StateTree, parent: string | undefined): ReadonlyArray<string> => {
219
+ const paths: Array<string> = []
220
+ for (const key of Object.keys(tree)) {
221
+ if (key.includes(".")) {
222
+ throw new Error(`Machine state keys cannot contain ".": "${key}"`)
223
+ }
224
+ const path = parent === undefined ? key : `${parent}.${key}`
225
+ const definition = getStateNodeDefinition(path, tree[key]!)
226
+ let node: Machine.StateNode
227
+ let childStates: Machine.StateTree | undefined
228
+ const base = { path, key, annotations: definition.annotations, order }
229
+ switch (definition.type) {
230
+ case "atomic":
231
+ node = {
232
+ ...base,
233
+ type: "atomic",
234
+ schema: definition.schema,
235
+ output: undefined,
236
+ history: undefined,
237
+ parent,
238
+ children: [],
239
+ initial: undefined
240
+ }
241
+ break
242
+ case "compound":
243
+ node = {
244
+ ...base,
245
+ type: "compound",
246
+ schema: definition.schema,
247
+ output: undefined,
248
+ history: undefined,
249
+ parent,
250
+ children: [],
251
+ initial: `${path}.${definition.initial}`
252
+ }
253
+ childStates = definition.states
254
+ break
255
+ case "parallel":
256
+ node = {
257
+ ...base,
258
+ type: "parallel",
259
+ schema: definition.schema,
260
+ output: definition.output,
261
+ history: undefined,
262
+ parent,
263
+ children: [],
264
+ initial: undefined
265
+ }
266
+ childStates = definition.states
267
+ break
268
+ case "final":
269
+ node = {
270
+ ...base,
271
+ type: "final",
272
+ schema: definition.schema,
273
+ output: definition.output,
274
+ history: undefined,
275
+ parent,
276
+ children: [],
277
+ initial: undefined
278
+ }
279
+ break
280
+ case "history":
281
+ if (parent === undefined) {
282
+ throw new Error(`Machine history state "${path}" must belong to a parent state`)
283
+ }
284
+ node = {
285
+ ...base,
286
+ type: "history",
287
+ schema: undefined,
288
+ output: undefined,
289
+ history: definition.history,
290
+ parent,
291
+ children: [],
292
+ initial: undefined
293
+ }
294
+ break
295
+ case "choice":
296
+ if (parent === undefined) {
297
+ throw new Error(`Machine choice state "${path}" must belong to a parent state`)
298
+ }
299
+ node = {
300
+ ...base,
301
+ type: "choice",
302
+ schema: undefined,
303
+ output: undefined,
304
+ history: undefined,
305
+ parent,
306
+ children: [],
307
+ initial: undefined
308
+ }
309
+ break
310
+ }
311
+ byPath.set(path, node)
312
+ order += 1
313
+ if (definition.type === "history" || definition.type === "choice") {
314
+ continue
315
+ }
316
+ paths.push(path)
317
+ if (childStates !== undefined) {
318
+ const children = compile(childStates, path)
319
+ if (node.type === "compound") {
320
+ if (!children.includes(node.initial) && byPath.get(node.initial)?.type !== "choice") {
321
+ throw new Error(`Machine.make expected compound state "${path}" initial child to exist`)
322
+ }
323
+ node = { ...node, children }
324
+ } else if (node.type === "parallel") {
325
+ node = { ...node, children }
326
+ } else {
327
+ throw new Error(`Machine state "${path}" cannot declare child states`)
328
+ }
329
+ byPath.set(path, node)
330
+ }
331
+ }
332
+ return paths
333
+ }
334
+
335
+ return {
336
+ byPath,
337
+ roots: compile(states, undefined)
338
+ } as Machine.StateNodes
339
+ }
340
+
341
+ const dynamicTransitionTargets = { type: "dynamic" } as const
342
+
343
+ const transitionTargets = (handler: unknown): Machine.TransitionTargets =>
344
+ typeof handler === "object" && handler !== null && "targets" in handler && handler.targets !== undefined
345
+ ? { type: "declared", paths: Array.from(handler.targets as ReadonlyArray<string>) }
346
+ : dynamicTransitionTargets
347
+
348
+ export const transitionDefinitions = (
349
+ machine: Machine.Any
350
+ ): ReadonlyArray<Machine.TransitionDefinition> => {
351
+ const definitions: Array<Machine.TransitionDefinition> = []
352
+ for (const node of machine.stateNodes.byPath.values()) {
353
+ const config = machine.handlers[node.path] as Machine.AnyStateConfig | undefined
354
+ if (config === undefined) {
355
+ continue
356
+ }
357
+ if (node.type === "choice") {
358
+ const choice = (config as any).choice
359
+ if (choice !== undefined) {
360
+ definitions.push({
361
+ source: node.path,
362
+ trigger: { type: "choice" },
363
+ reenter: false,
364
+ targets: transitionTargets(choice)
365
+ })
366
+ }
367
+ continue
368
+ }
369
+ for (const event of Reflect.ownKeys(config.on ?? {})) {
370
+ const handler = config.on?.[event]
371
+ definitions.push({
372
+ source: node.path,
373
+ trigger: { type: "event", event },
374
+ reenter: typeof handler === "object" && handler !== null && handler.reenter === true,
375
+ targets: transitionTargets(handler)
376
+ })
377
+ }
378
+ if (config.always !== undefined) {
379
+ definitions.push({
380
+ source: node.path,
381
+ trigger: { type: "always" },
382
+ reenter: false,
383
+ targets: transitionTargets(config.always)
384
+ })
385
+ }
386
+ if (config.onDone !== undefined) {
387
+ definitions.push({
388
+ source: node.path,
389
+ trigger: { type: "done" },
390
+ reenter: false,
391
+ targets: transitionTargets(config.onDone)
392
+ })
393
+ }
394
+ }
395
+ return definitions
396
+ }
397
+
398
+ export const makeTarget = <
399
+ const States extends Machine.StateSchemas,
400
+ const StateId extends Machine.StateIdentifier<States>
401
+ >(
402
+ path: StateId,
403
+ value: Machine.StateByIdentifier<States, StateId>,
404
+ options?: {
405
+ readonly snapshot?: Machine.SnapshotByIdentifier<States, StateId>
406
+ readonly values?: Partial<
407
+ {
408
+ readonly [AncestorStateId in Machine.StateIdentifier<States>]: Machine.StateByIdentifier<
409
+ States,
410
+ AncestorStateId
411
+ >
412
+ }
413
+ >
414
+ }
415
+ ): Machine.Target<States, StateId> =>
416
+ ({
417
+ [TargetTypeId]: TargetTypeId,
418
+ [TargetSnapshotTypeId]: options?.snapshot,
419
+ path,
420
+ value,
421
+ values: options?.values
422
+ }) as Machine.Target<States, StateId>
423
+
424
+ export const isTarget = (u: unknown): u is Machine.Target<any, any> => hasProperty(u, TargetTypeId)
425
+
426
+ export const makeStateInput = (input: unknown): StateInput => ({
427
+ [StateInputTypeId]: StateInputTypeId,
428
+ input
429
+ })
430
+
431
+ export const isStateInput = (u: unknown): u is StateInput => hasProperty(u, StateInputTypeId)
432
+
433
+ export const isSnapshot = (u: unknown): u is Machine.AtomicSnapshot<string, unknown> =>
434
+ hasProperty(u, "path") && hasProperty(u, "value")
435
+
436
+ export const getSnapshotByPath = (
437
+ snapshot: Machine.AtomicSnapshot<string, unknown>,
438
+ path: string,
439
+ parents?: Record<string, unknown>
440
+ ): Option.Option<Machine.AtomicSnapshot<string, unknown>> => {
441
+ if (snapshot.path === path) {
442
+ return Option.some(snapshot)
443
+ }
444
+ if (!path.startsWith(`${snapshot.path}.`)) {
445
+ return Option.none()
446
+ }
447
+ if (parents !== undefined) {
448
+ parents[snapshot.path] = snapshot.value
449
+ }
450
+ if (hasProperty(snapshot, "state") && isSnapshot(snapshot.state)) {
451
+ return getSnapshotByPath(snapshot.state, path, parents)
452
+ }
453
+ if (hasProperty(snapshot, "states") && typeof snapshot.states === "object" && snapshot.states !== null) {
454
+ for (const child of Object.values(snapshot.states)) {
455
+ if (isSnapshot(child)) {
456
+ const result = getSnapshotByPath(child, path, parents)
457
+ if (Option.isSome(result)) {
458
+ return result
459
+ }
460
+ }
461
+ }
462
+ }
463
+ return Option.none()
464
+ }
465
+
466
+ export const getNode = (machine: Machine.Any, path: string): Machine.StateNode => {
467
+ const node = machine.stateNodes.byPath.get(path)
468
+ if (node === undefined) {
469
+ throw new Error(`Machine expected state path "${path}" to exist`)
470
+ }
471
+ return node
472
+ }
473
+
474
+ export const getStateNodeSchema = (node: Machine.StateNode): Machine.TaggedSchema => {
475
+ if (node.schema === undefined) {
476
+ throw new Error(`Machine pseudo-state "${node.path}" has no active value schema`)
477
+ }
478
+ return node.schema
479
+ }
@@ -0,0 +1,102 @@
1
+ import * as Schema from "effect/Schema"
2
+ import * as SchemaAST from "effect/SchemaAST"
3
+ import { FastCheck } from "effect/testing"
4
+
5
+ /**
6
+ * Warning emitted when schema arbitrary generation must enforce an opaque
7
+ * filter through rejection sampling.
8
+ *
9
+ * @category models
10
+ * @since 0.4.0
11
+ */
12
+ export interface SchemaArbitraryOpaqueFilterWarning {
13
+ readonly _tag: "OpaqueFilter"
14
+ readonly path: ReadonlyArray<PropertyKey>
15
+ readonly description?: string
16
+ }
17
+
18
+ /**
19
+ * Non-fatal diagnostic emitted while deriving a schema arbitrary.
20
+ *
21
+ * @category models
22
+ * @since 0.4.0
23
+ */
24
+ export type SchemaArbitraryWarning = SchemaArbitraryOpaqueFilterWarning
25
+
26
+ /**
27
+ * Diagnostics collected while deriving a schema arbitrary.
28
+ *
29
+ * @category models
30
+ * @since 0.4.0
31
+ */
32
+ export interface SchemaArbitraryReport {
33
+ readonly warnings: ReadonlyArray<SchemaArbitraryWarning>
34
+ }
35
+
36
+ const reportChecks = (
37
+ warnings: Array<SchemaArbitraryWarning>,
38
+ checks: SchemaAST.Checks | undefined,
39
+ path: ReadonlyArray<PropertyKey>
40
+ ): void => {
41
+ const visit = (check: SchemaAST.Check<unknown>, covered: boolean): void => {
42
+ const arbitrary = check.annotations?.arbitrary
43
+ const nextCovered = covered || arbitrary?.constraint !== undefined || arbitrary?.candidate !== undefined
44
+ if (check._tag !== "Filter") {
45
+ for (const child of check.checks) visit(child, nextCovered)
46
+ } else if (!nextCovered) {
47
+ const description = check.annotations?.representation?.id ?? check.annotations?.identifier ??
48
+ check.annotations?.expected
49
+ warnings.push({
50
+ _tag: "OpaqueFilter",
51
+ path,
52
+ ...(description === undefined ? {} : { description })
53
+ })
54
+ }
55
+ }
56
+ checks?.forEach((check) => visit(check, false))
57
+ }
58
+
59
+ const reportFor = (ast: SchemaAST.AST): SchemaArbitraryReport => {
60
+ const warnings: Array<SchemaArbitraryWarning> = []
61
+ const stack = new WeakSet<SchemaAST.AST>()
62
+ const visit = (ast: SchemaAST.AST, path: ReadonlyArray<PropertyKey>): void => {
63
+ if (stack.has(ast)) return
64
+ stack.add(ast)
65
+ reportChecks(warnings, ast.checks, path)
66
+ switch (ast._tag) {
67
+ case "Declaration":
68
+ ast.typeParameters.forEach((typeParameter) => visit(typeParameter, path))
69
+ break
70
+ case "Arrays": {
71
+ const elements = [...ast.elements, ...ast.rest]
72
+ elements.forEach((type, index) => visit(type, [...path, index]))
73
+ break
74
+ }
75
+ case "Objects":
76
+ ast.propertySignatures.forEach((property) => visit(property.type, [...path, property.name]))
77
+ ast.indexSignatures.forEach((index) => {
78
+ visit(index.parameter, path)
79
+ visit(index.type, path)
80
+ })
81
+ break
82
+ case "Union":
83
+ ast.types.forEach((type) => visit(type, path))
84
+ break
85
+ case "TemplateLiteral":
86
+ ast.parts.forEach((part, index) => visit(SchemaAST.toEncoded(part), [...path, index]))
87
+ break
88
+ case "Suspend":
89
+ visit(ast.thunk(), path)
90
+ break
91
+ }
92
+ stack.delete(ast)
93
+ }
94
+ visit(ast, [])
95
+ return { warnings }
96
+ }
97
+
98
+ /** @internal */
99
+ export const toArbitraryWithReport = <S extends Schema.Constraint>(schema: S) => ({
100
+ value: Schema.toArbitrary(schema)(FastCheck),
101
+ report: reportFor(schema.ast)
102
+ })