@typeonce/effect-machine 0.15.0 → 0.17.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 (85) hide show
  1. package/README.md +115 -95
  2. package/dist/Machine.d.ts +464 -337
  3. package/dist/Machine.d.ts.map +1 -1
  4. package/dist/Machine.js +72 -107
  5. package/dist/Machine.js.map +1 -1
  6. package/dist/internal/machine/activities.d.ts +2 -0
  7. package/dist/internal/machine/activities.d.ts.map +1 -1
  8. package/dist/internal/machine/activities.js +4 -0
  9. package/dist/internal/machine/activities.js.map +1 -1
  10. package/dist/internal/machine/atom.d.ts +7 -7
  11. package/dist/internal/machine/atom.d.ts.map +1 -1
  12. package/dist/internal/machine/atom.js.map +1 -1
  13. package/dist/internal/machine/cluster.d.ts +2 -2
  14. package/dist/internal/machine/cluster.d.ts.map +1 -1
  15. package/dist/internal/machine/cluster.js +6 -5
  16. package/dist/internal/machine/cluster.js.map +1 -1
  17. package/dist/internal/machine/executionPlan.d.ts.map +1 -1
  18. package/dist/internal/machine/executionPlan.js +16 -4
  19. package/dist/internal/machine/executionPlan.js.map +1 -1
  20. package/dist/internal/machine/invocation.d.ts +1 -1
  21. package/dist/internal/machine/invocation.d.ts.map +1 -1
  22. package/dist/internal/machine/invocation.js +25 -3
  23. package/dist/internal/machine/invocation.js.map +1 -1
  24. package/dist/internal/machine/invocationEvent.d.ts +8 -0
  25. package/dist/internal/machine/invocationEvent.d.ts.map +1 -1
  26. package/dist/internal/machine/invocationEvent.js +8 -0
  27. package/dist/internal/machine/invocationEvent.js.map +1 -1
  28. package/dist/internal/machine/machine.d.ts +8 -6
  29. package/dist/internal/machine/machine.d.ts.map +1 -1
  30. package/dist/internal/machine/machine.js +308 -71
  31. package/dist/internal/machine/machine.js.map +1 -1
  32. package/dist/internal/machine/planner.d.ts +26 -4
  33. package/dist/internal/machine/planner.d.ts.map +1 -1
  34. package/dist/internal/machine/planner.js +76 -31
  35. package/dist/internal/machine/planner.js.map +1 -1
  36. package/dist/internal/machine/runtime.d.ts +1 -0
  37. package/dist/internal/machine/runtime.d.ts.map +1 -1
  38. package/dist/internal/machine/runtime.js +25 -16
  39. package/dist/internal/machine/runtime.js.map +1 -1
  40. package/dist/internal/machine/stateDefinition.d.ts.map +1 -1
  41. package/dist/internal/machine/stateDefinition.js +14 -0
  42. package/dist/internal/machine/stateDefinition.js.map +1 -1
  43. package/dist/internal/machine/topology.d.ts +20 -0
  44. package/dist/internal/machine/topology.d.ts.map +1 -1
  45. package/dist/internal/machine/topology.js +33 -6
  46. package/dist/internal/machine/topology.js.map +1 -1
  47. package/dist/internal/testing/machine/finiteModel.d.ts.map +1 -1
  48. package/dist/internal/testing/machine/finiteModel.js +15 -20
  49. package/dist/internal/testing/machine/finiteModel.js.map +1 -1
  50. package/dist/internal/testing/machine/transitionCoverage.d.ts.map +1 -1
  51. package/dist/internal/testing/machine/transitionCoverage.js +8 -2
  52. package/dist/internal/testing/machine/transitionCoverage.js.map +1 -1
  53. package/dist/internal/testing/machine/verification.d.ts.map +1 -1
  54. package/dist/internal/testing/machine/verification.js +6 -0
  55. package/dist/internal/testing/machine/verification.js.map +1 -1
  56. package/dist/testing/MachineTest.d.ts +13 -12
  57. package/dist/testing/MachineTest.d.ts.map +1 -1
  58. package/dist/testing/MachineTest.js +5 -8
  59. package/dist/testing/MachineTest.js.map +1 -1
  60. package/dist/unstable/cluster/ClusterMachine.d.ts +2 -2
  61. package/dist/unstable/cluster/ClusterMachine.d.ts.map +1 -1
  62. package/dist/unstable/cluster/ClusterMachine.js.map +1 -1
  63. package/dist/unstable/reactivity/AtomMachine.d.ts +12 -12
  64. package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
  65. package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
  66. package/docs/agent-guide.md +182 -159
  67. package/package.json +1 -1
  68. package/src/Machine.ts +1073 -700
  69. package/src/internal/machine/activities.ts +7 -0
  70. package/src/internal/machine/atom.ts +20 -15
  71. package/src/internal/machine/cluster.ts +14 -9
  72. package/src/internal/machine/executionPlan.ts +14 -4
  73. package/src/internal/machine/invocation.ts +39 -4
  74. package/src/internal/machine/invocationEvent.ts +16 -0
  75. package/src/internal/machine/machine.ts +460 -86
  76. package/src/internal/machine/planner.ts +106 -30
  77. package/src/internal/machine/runtime.ts +61 -25
  78. package/src/internal/machine/stateDefinition.ts +39 -0
  79. package/src/internal/machine/topology.ts +59 -2
  80. package/src/internal/testing/machine/finiteModel.ts +18 -21
  81. package/src/internal/testing/machine/transitionCoverage.ts +8 -2
  82. package/src/internal/testing/machine/verification.ts +11 -0
  83. package/src/testing/MachineTest.ts +16 -11
  84. package/src/unstable/cluster/ClusterMachine.ts +8 -4
  85. package/src/unstable/reactivity/AtomMachine.ts +19 -12
@@ -25,8 +25,12 @@ export const ChoiceTargetTypeId: unique symbol = Symbol("effect/Machine/ChoiceTa
25
25
 
26
26
  export const NoTargetTypeId: unique symbol = Symbol("effect/Machine/NoTarget")
27
27
 
28
+ export const DeclinedTypeId: unique symbol = Symbol("effect/Machine/Declined")
29
+
28
30
  export const TargetSelectionTypeId: unique symbol = Symbol("effect/Machine/TargetSelection")
29
31
 
32
+ export const SelectedBranchTypeId: unique symbol = Symbol("effect/Machine/SelectedBranch")
33
+
30
34
  interface StateInput {
31
35
  readonly [StateInputTypeId]: typeof StateInputTypeId
32
36
  readonly input: unknown
@@ -64,6 +68,11 @@ export interface NoTarget {
64
68
  readonly [NoTargetTypeId]: typeof NoTargetTypeId
65
69
  }
66
70
 
71
+ /** Internal marker returned when a declinable transition is not enabled. */
72
+ export interface Declined {
73
+ readonly [DeclinedTypeId]: typeof DeclinedTypeId
74
+ }
75
+
67
76
  export type TargetSelectionKind = "state" | "initial" | "history" | "choice" | "none"
68
77
 
69
78
  export type TargetSelectionScope = "local" | "branch" | "full" | "initial"
@@ -76,6 +85,15 @@ export interface TargetSelection {
76
85
  readonly path: string | undefined
77
86
  }
78
87
 
88
+ /** One branch selection returned by a compiled branching transition. */
89
+ export interface SelectedBranch {
90
+ readonly [SelectedBranchTypeId]: typeof SelectedBranchTypeId
91
+ readonly owner: object
92
+ readonly branchIndex: number
93
+ readonly branchKey: string
94
+ readonly result: unknown
95
+ }
96
+
79
97
  export const makeTargetSelection = (
80
98
  kind: TargetSelectionKind,
81
99
  path?: string,
@@ -88,8 +106,27 @@ export const makeTargetSelection = (
88
106
  path
89
107
  })
90
108
 
109
+ /** Source-independent definition-time selection for an explicitly targetless transition. */
110
+ export const noneTargetSelection: TargetSelection = makeTargetSelection("none", undefined, "local")
111
+
91
112
  export const isTargetSelection = (u: unknown): u is TargetSelection => hasProperty(u, TargetSelectionTypeId)
92
113
 
114
+ export const makeSelectedBranch = (
115
+ owner: object,
116
+ branchIndex: number,
117
+ branchKey: string,
118
+ result: unknown
119
+ ): SelectedBranch =>
120
+ Object.freeze({
121
+ [SelectedBranchTypeId]: SelectedBranchTypeId,
122
+ owner,
123
+ branchIndex,
124
+ branchKey,
125
+ result
126
+ })
127
+
128
+ export const isSelectedBranch = (u: unknown): u is SelectedBranch => hasProperty(u, SelectedBranchTypeId)
129
+
93
130
  const noTarget = Object.freeze({
94
131
  [NoTargetTypeId]: NoTargetTypeId
95
132
  }) as NoTarget
@@ -98,6 +135,14 @@ export const makeNoTarget = (): Machine.NoTarget => noTarget
98
135
 
99
136
  export const isNoTarget = (u: unknown): u is Machine.NoTarget => hasProperty(u, NoTargetTypeId)
100
137
 
138
+ const declined = Object.freeze({
139
+ [DeclinedTypeId]: DeclinedTypeId
140
+ }) as Declined
141
+
142
+ export const makeDeclined = (): Machine.Declined => declined
143
+
144
+ export const isDeclined = (u: unknown): u is Machine.Declined => hasProperty(u, DeclinedTypeId)
145
+
101
146
  export const makeHistoryTarget = (path: string, parent: string): HistoryTarget => ({
102
147
  [HistoryTargetTypeId]: HistoryTargetTypeId,
103
148
  path,
@@ -414,6 +459,11 @@ const transitionBranches = (handler: unknown): ReadonlyArray<Machine.TransitionB
414
459
  ? Array.from(handler.branches as ReadonlyArray<Machine.TransitionBranch>)
415
460
  : []
416
461
 
462
+ const transitionAcceptance = (handler: unknown): Machine.TransitionAcceptance =>
463
+ typeof handler === "object" && handler !== null && "declinable" in handler && handler.declinable === true
464
+ ? "declinable"
465
+ : "required"
466
+
417
467
  export const transitionDefinitions = (
418
468
  machine: Machine.Any
419
469
  ): ReadonlyArray<Machine.TransitionDefinition> => {
@@ -430,6 +480,7 @@ export const transitionDefinitions = (
430
480
  source: node.path,
431
481
  trigger: { type: "choice" },
432
482
  reenter: false,
483
+ acceptance: "required",
433
484
  branches: transitionBranches(choice)
434
485
  })
435
486
  }
@@ -441,6 +492,7 @@ export const transitionDefinitions = (
441
492
  source: node.path,
442
493
  trigger: { type: "event", event },
443
494
  reenter: hasProperty(handler, "reenter") && handler.reenter === true,
495
+ acceptance: transitionAcceptance(handler),
444
496
  branches: transitionBranches(handler)
445
497
  })
446
498
  }
@@ -449,6 +501,7 @@ export const transitionDefinitions = (
449
501
  source: node.path,
450
502
  trigger: { type: "always" },
451
503
  reenter: false,
504
+ acceptance: transitionAcceptance(config.always),
452
505
  branches: transitionBranches(config.always)
453
506
  })
454
507
  }
@@ -457,6 +510,7 @@ export const transitionDefinitions = (
457
510
  source: node.path,
458
511
  trigger: { type: "done" },
459
512
  reenter: false,
513
+ acceptance: transitionAcceptance(config.onDone),
460
514
  branches: transitionBranches(config.onDone)
461
515
  })
462
516
  }
@@ -467,8 +521,10 @@ export const transitionDefinitions = (
467
521
  : [config.invoke]
468
522
  for (const invoke of invokes) {
469
523
  const id = "child" in invoke ? String(invoke.child.id) : String(invoke.id)
470
- for (const outcome of ["done", "failure", "snapshot"] as const) {
471
- const handler = outcome === "done"
524
+ for (const outcome of ["element", "done", "failure", "snapshot"] as const) {
525
+ const handler = outcome === "element"
526
+ ? invoke.onElement
527
+ : outcome === "done"
472
528
  ? invoke.onDone
473
529
  : outcome === "failure"
474
530
  ? invoke.onFailure
@@ -478,6 +534,7 @@ export const transitionDefinitions = (
478
534
  source: node.path,
479
535
  trigger: { type: "invoke", id, outcome },
480
536
  reenter: typeof handler === "object" && handler !== null && handler.reenter === true,
537
+ acceptance: transitionAcceptance(handler),
481
538
  branches: transitionBranches(handler)
482
539
  })
483
540
  }
@@ -1316,7 +1316,7 @@ const selectHistoryTarget = (builder: Record<string, any>, path: string): unknow
1316
1316
  const parts = path.split(".")
1317
1317
  let current: any = builder
1318
1318
  for (let index = 0; index < parts.length - 1; index++) current = current[parts[index]!]
1319
- return current[parts[parts.length - 1]!]()
1319
+ return current[parts[parts.length - 1]!]
1320
1320
  }
1321
1321
 
1322
1322
  const selectableDefinitionTarget = (
@@ -1356,7 +1356,7 @@ const selectDefinitionTarget = (
1356
1356
  const parts = selectable.split(".")
1357
1357
  for (const part of parts) current = current[part]
1358
1358
  if (typeof current === "function") return current()
1359
- return current.initial()
1359
+ return current.initial
1360
1360
  }
1361
1361
 
1362
1362
  const resolveDefinitionTarget = (
@@ -1415,11 +1415,10 @@ const makeHandlers = (
1415
1415
  if (node._tag === "History") continue
1416
1416
  if (node._tag === "Choice") {
1417
1417
  handlers[node.key] = {
1418
- choice: (Machine.transition as any)({
1419
- target: (to: Record<string, any>) => selectDefinitionTarget(to, path, node.selected, byPath) as any,
1420
- resolve: ({ target }: { readonly target: any }) =>
1421
- resolveDefinitionTarget(target, path, node.selected, byPath)
1422
- } as any)
1418
+ choice: (to: Record<string, any>) =>
1419
+ (selectDefinitionTarget(to, path, node.selected, byPath) as any).resolve(
1420
+ ({ target }: { readonly target: any }) => resolveDefinitionTarget(target, path, node.selected, byPath)
1421
+ )
1423
1422
  }
1424
1423
  continue
1425
1424
  }
@@ -1432,17 +1431,16 @@ const makeHandlers = (
1432
1431
  let onDone: unknown
1433
1432
  for (const transition of transitions.values()) {
1434
1433
  if (transition.source !== path) continue
1435
- const config = (Machine.transition as any)({
1436
- ...("reenter" in transition ? { reenter: transition.reenter } : {}),
1437
- target: (to: Record<string, any>) =>
1438
- transition.target === undefined
1439
- ? to.none()
1440
- : selectDefinitionTarget(to, path, transition.target, byPath),
1441
- resolve: transition.target === undefined
1434
+ const config = (to: Record<string, any>) => {
1435
+ const selected = transition.target === undefined
1436
+ ? to.none
1437
+ : selectDefinitionTarget(to, path, transition.target, byPath)
1438
+ const resolve = transition.target === undefined
1442
1439
  ? () => undefined
1443
1440
  : ({ target }: { readonly target: any }) =>
1444
1441
  resolveDefinitionTarget(target, path, transition.target!, byPath, transition.targetValue)
1445
- } as any)
1442
+ return selected.resolve(resolve, "reenter" in transition ? { reenter: transition.reenter } : undefined)
1443
+ }
1446
1444
  if (transition.trigger.type === "event") on[transition.trigger.event] = config
1447
1445
  else if (transition.trigger.type === "always") always = config
1448
1446
  else onDone = config
@@ -1515,13 +1513,12 @@ export const compileModel = (model: FiniteModel): Machine.Machine.Any => {
1515
1513
  const machine = Machine.make({
1516
1514
  states: defined.states as any,
1517
1515
  events: Machine.events(...eventSchemas) as any,
1518
- initial: {
1519
- target: (to: Record<string, any>) => {
1520
- const selected = to[initial.path]
1521
- return typeof selected === "function" ? selected() : selected.initial()
1522
- },
1523
- resolve: ({ target }: { readonly target: any }) =>
1516
+ initial: (to: Record<string, any>) => {
1517
+ const selected = to[initial.path]
1518
+ const selection = typeof selected === "function" ? selected() : selected.initial
1519
+ return selection.resolve(({ target }: { readonly target: any }) =>
1524
1520
  selectSnapshot({ [initial.path]: target }, initial.path, byPath, [initial.path], 0) as any
1521
+ )
1525
1522
  }
1526
1523
  } as any)
1527
1524
  const transitions = new Map(model.transitions.map((transition) => [
@@ -66,6 +66,7 @@ export const makeTransitionCoverageCollector = <M extends AnyMachine>(
66
66
  source: definition.source,
67
67
  trigger: definition.trigger,
68
68
  reenter: definition.reenter,
69
+ acceptance: definition.acceptance,
69
70
  branches: definition.branches
70
71
  })
71
72
  )
@@ -76,13 +77,16 @@ export const makeTransitionCoverageCollector = <M extends AnyMachine>(
76
77
  branchOffsets.push(branches.length)
77
78
  const definition = definitions[definitionIndex]!
78
79
  definition.branches.forEach((branch, branchIndex) => {
80
+ const branchKey = branch.type === "branch" ? branch.key : undefined
79
81
  branches.push({
80
- id: `transition:${definitionIndex}:branch:${branchIndex}`,
82
+ id: `transition:${definitionIndex}:branch:${branchKey ?? "direct"}`,
81
83
  definitionIndex,
82
84
  branchIndex,
85
+ branchKey,
83
86
  source: definition.source,
84
87
  trigger: definition.trigger,
85
88
  reenter: definition.reenter,
89
+ acceptance: definition.acceptance,
86
90
  branch
87
91
  })
88
92
  })
@@ -100,9 +104,11 @@ export const makeTransitionCoverageCollector = <M extends AnyMachine>(
100
104
  if (definitionIndex === -1) continue
101
105
  definitionHits.add(definitionIndex)
102
106
  const definition = definitions[definitionIndex]!
107
+ const branch = definition.branches[retained.branchIndex]
103
108
  if (
104
109
  Number.isSafeInteger(retained.branchIndex) && retained.branchIndex >= 0 &&
105
- retained.branchIndex < definition.branches.length
110
+ retained.branchIndex < definition.branches.length &&
111
+ retained.branchKey === (branch?.type === "branch" ? branch.key : undefined)
106
112
  ) {
107
113
  branchHits.add(branchOffsets[definitionIndex]! + retained.branchIndex)
108
114
  }
@@ -1512,6 +1512,17 @@ export const verify = <M extends AnyMachine>(
1512
1512
  return undefined
1513
1513
  }
1514
1514
  const branch = definition.branches[transition.branchIndex]!
1515
+ const expectedBranchKey = branch.type === "branch" ? branch.key : undefined
1516
+ if (transition.branchKey !== expectedBranchKey) {
1517
+ add(
1518
+ "definitions.branchKey",
1519
+ location,
1520
+ `retained transition from "${transition.source}" selected branch key ` +
1521
+ `"${String(transition.branchKey)}" instead of "${String(expectedBranchKey)}"`,
1522
+ transition.source
1523
+ )
1524
+ return undefined
1525
+ }
1515
1526
  if (!targetWithinSelection(transition.target, branch, byPath)) {
1516
1527
  const expected = branch.selection.kind === "none"
1517
1528
  ? "an explicitly targetless result"
@@ -138,6 +138,10 @@ type ReadyMachine<M extends AnyMachine> =
138
138
  Machine.Machine.OutputStates<M>
139
139
  >
140
140
 
141
+ type RootReadyMachine<M extends AnyMachine> =
142
+ & ReadyMachine<M>
143
+ & Machine.Machine.RootCompatible<Machine.Machine.ParentEvents<M>>
144
+
141
145
  /**
142
146
  * A generated public-input scenario for a machine.
143
147
  *
@@ -238,10 +242,8 @@ export interface Scenarios<M extends AnyMachine> {
238
242
  * }).handle({
239
243
  * Idle: {
240
244
  * on: {
241
- * Reset: Machine.transition({
242
- * target: (to) => to.full.Idle(),
243
- * resolve: ({ target }) => target.from()
244
- * })
245
+ * Reset: (to) =>
246
+ * to.full.Idle().resolve(({ target }) => target.from())
245
247
  * }
246
248
  * }
247
249
  * })
@@ -881,7 +883,7 @@ export { PlannerRuntimeAgreementError } from "../internal/testing/machine/verifi
881
883
  * @since 0.4.0
882
884
  */
883
885
  export const assertPlannerRuntimeAgreement: <M extends AnyMachine, Error, Output>(
884
- machine: ReadyMachine<M>,
886
+ machine: RootReadyMachine<M>,
885
887
  transcript: CausalRuntimeEvidence<M, Error, Output>
886
888
  ) => Effect.Effect<void, internal.PlannerRuntimeAgreementError<M>, RunServices<M>> =
887
889
  internal.assertPlannerRuntimeAgreement
@@ -1447,10 +1449,9 @@ export type ExploreOptions<M extends AnyMachine, Key extends ExplorationKey = Ex
1447
1449
  * }).handle({
1448
1450
  * Count: {
1449
1451
  * on: {
1450
- * Increment: Machine.transition({
1451
- * target: (to) => to.full.Count(),
1452
- * resolve: ({ state, target }) => target(new Count({ value: state.value + 1 }))
1453
- * })
1452
+ * Increment: (to) =>
1453
+ * to.full.Count().resolve(({ state, target }) =>
1454
+ * target(new Count({ value: state.value + 1 })))
1454
1455
  * }
1455
1456
  * }
1456
1457
  * })
@@ -1465,7 +1466,7 @@ export type ExploreOptions<M extends AnyMachine, Key extends ExplorationKey = Ex
1465
1466
  * @since 0.4.0
1466
1467
  */
1467
1468
  export const explore: <M extends AnyMachine, Key extends ExplorationKey>(
1468
- machine: ReadyMachine<M>,
1469
+ machine: RootReadyMachine<M>,
1469
1470
  options: ExploreOptions<M, Key>
1470
1471
  ) => Effect.Effect<
1471
1472
  Exploration<M, Key>,
@@ -1646,7 +1647,7 @@ export type RunServices<M extends AnyMachine> = IsAny<
1646
1647
  * @since 0.4.0
1647
1648
  */
1648
1649
  export const run: <M extends AnyMachine>(
1649
- machine: ReadyMachine<M>,
1650
+ machine: RootReadyMachine<M>,
1650
1651
  scenario: Scenario<M>
1651
1652
  ) => Effect.Effect<Trace<M>, RunFailure<RunError<M>, M>, RunServices<M>> = internal.run
1652
1653
 
@@ -1703,6 +1704,7 @@ export interface TransitionDefinitionCoverageItem<
1703
1704
  readonly source: SourcePath
1704
1705
  readonly trigger: Machine.Machine.TransitionTrigger<EventTag>
1705
1706
  readonly reenter: boolean
1707
+ readonly acceptance: Machine.Machine.TransitionAcceptance
1706
1708
  readonly branches: ReadonlyArray<Machine.Machine.TransitionBranch<TargetPath>>
1707
1709
  }
1708
1710
 
@@ -1721,9 +1723,11 @@ export interface TransitionBranchCoverageItem<
1721
1723
  readonly id: string
1722
1724
  readonly definitionIndex: number
1723
1725
  readonly branchIndex: number
1726
+ readonly branchKey: string | undefined
1724
1727
  readonly source: SourcePath
1725
1728
  readonly trigger: Machine.Machine.TransitionTrigger<EventTag>
1726
1729
  readonly reenter: boolean
1730
+ readonly acceptance: Machine.Machine.TransitionAcceptance
1727
1731
  readonly branch: Machine.Machine.TransitionBranch<TargetPath>
1728
1732
  }
1729
1733
 
@@ -2063,6 +2067,7 @@ export type VerificationLaw =
2063
2067
  | "definitions.initial"
2064
2068
  | "definitions.transition"
2065
2069
  | "definitions.branchIndex"
2070
+ | "definitions.branchKey"
2066
2071
  | "definitions.selection"
2067
2072
  | "definitions.resolution"
2068
2073
 
@@ -342,7 +342,8 @@ export const make: <
342
342
  Output,
343
343
  Emits extends ReadonlyArray<Machine.Machine.TaggedSchema>,
344
344
  OutputStates extends Machine.Machine.StateIdentifier<States>,
345
- InputEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = Events
345
+ InputEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = Events,
346
+ ParentEvents extends ReadonlyArray<Machine.Machine.TaggedSchema> = readonly []
346
347
  >(
347
348
  type: Type,
348
349
  machine:
@@ -359,9 +360,11 @@ export const make: <
359
360
  Output,
360
361
  Emits,
361
362
  OutputStates,
362
- InputEvents
363
+ InputEvents,
364
+ ParentEvents
363
365
  >
364
- & EnsureExecutable<States, UnhandledStates, OutputStates>,
366
+ & EnsureExecutable<States, UnhandledStates, OutputStates>
367
+ & Machine.Machine.RootCompatible<ParentEvents>,
365
368
  options: {
366
369
  readonly version: string
367
370
  },
@@ -381,7 +384,8 @@ export const make: <
381
384
  Output,
382
385
  Emits,
383
386
  OutputStates,
384
- InputEvents
387
+ InputEvents,
388
+ ParentEvents
385
389
  >,
386
390
  | ExcludeCompatibleRuntime<
387
391
  Machine.ExecutionServices<R | InitialR>,
@@ -159,11 +159,11 @@ export interface MachineAtom<State, Event, Error = never, Output = never, StartE
159
159
  ) => ChildMachineAtom<Child, StartError>
160
160
  }
161
161
 
162
- type RefState<Ref> = Ref extends Machine.MachineRef<infer State, any, any, any> ? State : never
162
+ type RefState<Ref> = Ref extends Machine.MachineRef<infer State, any, any, any, any> ? State : never
163
163
 
164
- type RefError<Ref> = Ref extends Machine.MachineRef<any, any, infer Error, any> ? Error : never
164
+ type RefError<Ref> = Ref extends Machine.MachineRef<any, any, infer Error, any, any> ? Error : never
165
165
 
166
- type RefOutput<Ref> = Ref extends Machine.MachineRef<any, any, any, infer Output> ? Output : never
166
+ type RefOutput<Ref> = Ref extends Machine.MachineRef<any, any, any, infer Output, any> ? Output : never
167
167
  type RefEmitted<Ref> = Ref extends Machine.MachineRef<any, any, any, any, infer Emitted> ? Emitted : never
168
168
 
169
169
  /**
@@ -305,7 +305,7 @@ export interface ChildMachineAtom<Child extends Machine.ChildMachine.Any, StartE
305
305
  ) => ChildMachineAtom<Nested, StartError>
306
306
  }
307
307
 
308
- type BridgeStartError<Bridge> = Bridge extends MachineAtom<any, any, any, any, infer StartError> ? StartError
308
+ type BridgeStartError<Bridge> = Bridge extends MachineAtom<any, never, any, any, infer StartError, any> ? StartError
309
309
  : Bridge extends ChildMachineAtom<any, infer StartError> ? StartError
310
310
  : never
311
311
 
@@ -317,7 +317,7 @@ type BridgeStartError<Bridge> = Bridge extends MachineAtom<any, any, any, any, i
317
317
  * @since 0.4.0
318
318
  */
319
319
  export type ChildOf<
320
- Parent extends MachineAtom<any, any, any, any, any> | ChildMachineAtom<any, any>,
320
+ Parent extends MachineAtom<any, never, any, any, any, any> | ChildMachineAtom<any, any>,
321
321
  Child extends Machine.ChildMachine.Any
322
322
  > = ChildMachineAtom<Child, BridgeStartError<Parent>>
323
323
 
@@ -389,8 +389,9 @@ export const select: <
389
389
  Error,
390
390
  Output,
391
391
  StartError,
392
+ Emitted,
392
393
  const Path extends ValuedSnapshotIdentifier<State>
393
- >(self: MachineAtom<State, Event, Error, Output, StartError>, path: Path) => Atom.Atom<
394
+ >(self: MachineAtom<State, Event, Error, Output, StartError, Emitted>, path: Path) => Atom.Atom<
394
395
  AsyncResult.AsyncResult<Option.Option<SnapshotValueByIdentifier<State, Path>>, StartError | Error>
395
396
  > = internal.select
396
397
 
@@ -410,8 +411,9 @@ export const selectSnapshot: <
410
411
  Error,
411
412
  Output,
412
413
  StartError,
414
+ Emitted,
413
415
  const Path extends SnapshotIdentifier<State>
414
- >(self: MachineAtom<State, Event, Error, Output, StartError>, path: Path) => Atom.Atom<
416
+ >(self: MachineAtom<State, Event, Error, Output, StartError, Emitted>, path: Path) => Atom.Atom<
415
417
  AsyncResult.AsyncResult<Option.Option<SnapshotByIdentifier<State, Path>>, StartError | Error>
416
418
  > = internal.selectSnapshot
417
419
 
@@ -503,9 +505,10 @@ export const matches: <
503
505
  Error,
504
506
  Output,
505
507
  StartError,
508
+ Emitted,
506
509
  const Path extends SnapshotIdentifier<State>
507
510
  >(
508
- self: MachineAtom<State, Event, Error, Output, StartError>,
511
+ self: MachineAtom<State, Event, Error, Output, StartError, Emitted>,
509
512
  path: Path
510
513
  ) => Atom.Atom<AsyncResult.AsyncResult<boolean, StartError | Error>> = internal.matches
511
514
 
@@ -625,7 +628,8 @@ export interface Bound<Services, RuntimeError = never> {
625
628
  machine:
626
629
  & M
627
630
  & EnsureBoundRequirements<Services, NoInfer<M>>
628
- & EnsureMachineExecutable<NoInfer<M>>,
631
+ & EnsureMachineExecutable<NoInfer<M>>
632
+ & Machine.Machine.RootCompatible<Machine.Machine.ParentEvents<NoInfer<M>>>,
629
633
  ...args: MachineInputArgsOf<M>
630
634
  ) => MachineAtomOf<M, RuntimeError>
631
635
 
@@ -634,7 +638,8 @@ export interface Bound<Services, RuntimeError = never> {
634
638
  machine:
635
639
  & M
636
640
  & EnsureBoundResumeRequirements<Services, NoInfer<M>>
637
- & EnsureMachineExecutable<NoInfer<M>>,
641
+ & EnsureMachineExecutable<NoInfer<M>>
642
+ & Machine.Machine.RootCompatible<Machine.Machine.ParentEvents<NoInfer<M>>>,
638
643
  snapshot: Machine.Machine.Snapshot<Machine.Machine.States<M>>
639
644
  ) => ResumedMachineAtomOf<M, RuntimeError>
640
645
  }
@@ -711,7 +716,8 @@ export const make: {
711
716
  Machine.Machine.EmitOf<Emits>
712
717
  >
713
718
  >
714
- & EnsureExecutable<States, UnhandledStates, OutputStates>,
719
+ & EnsureExecutable<States, UnhandledStates, OutputStates>
720
+ & Machine.Machine.RootCompatible<ParentEvents>,
715
721
  ...args: [...Machine.Machine.InputArgs<Input>]
716
722
  ): MachineAtom<
717
723
  Machine.Machine.Snapshot<States>,
@@ -738,7 +744,8 @@ export const resume: {
738
744
  machine:
739
745
  & M
740
746
  & EnsureNoExternalRequirements<MachineResumeRequirementsOf<NoInfer<M>>>
741
- & EnsureMachineExecutable<NoInfer<M>>,
747
+ & EnsureMachineExecutable<NoInfer<M>>
748
+ & Machine.Machine.RootCompatible<Machine.Machine.ParentEvents<NoInfer<M>>>,
742
749
  snapshot: Machine.Machine.Snapshot<Machine.Machine.States<M>>
743
750
  ): ResumedMachineAtomOf<M, never>
744
751
  } = internal.resume