@typeonce/effect-machine 0.12.0 → 0.13.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 (80) hide show
  1. package/README.md +56 -4
  2. package/dist/Machine.d.ts +353 -84
  3. package/dist/Machine.d.ts.map +1 -1
  4. package/dist/Machine.js +12 -10
  5. package/dist/Machine.js.map +1 -1
  6. package/dist/internal/machine/atom.d.ts +1 -0
  7. package/dist/internal/machine/atom.d.ts.map +1 -1
  8. package/dist/internal/machine/atom.js +23 -0
  9. package/dist/internal/machine/atom.js.map +1 -1
  10. package/dist/internal/machine/commandRuntime.d.ts.map +1 -1
  11. package/dist/internal/machine/commandRuntime.js +2 -5
  12. package/dist/internal/machine/commandRuntime.js.map +1 -1
  13. package/dist/internal/machine/configuration.d.ts +5 -0
  14. package/dist/internal/machine/configuration.d.ts.map +1 -1
  15. package/dist/internal/machine/configuration.js +6 -2
  16. package/dist/internal/machine/configuration.js.map +1 -1
  17. package/dist/internal/machine/executionPlan.d.ts +1 -0
  18. package/dist/internal/machine/executionPlan.d.ts.map +1 -1
  19. package/dist/internal/machine/executionPlan.js +43 -18
  20. package/dist/internal/machine/executionPlan.js.map +1 -1
  21. package/dist/internal/machine/initialization.d.ts +5 -0
  22. package/dist/internal/machine/initialization.d.ts.map +1 -0
  23. package/dist/internal/machine/initialization.js +61 -0
  24. package/dist/internal/machine/initialization.js.map +1 -0
  25. package/dist/internal/machine/inspectionRuntime.d.ts +25 -0
  26. package/dist/internal/machine/inspectionRuntime.d.ts.map +1 -0
  27. package/dist/internal/machine/inspectionRuntime.js +79 -0
  28. package/dist/internal/machine/inspectionRuntime.js.map +1 -0
  29. package/dist/internal/machine/invocation.d.ts +2 -1
  30. package/dist/internal/machine/invocation.d.ts.map +1 -1
  31. package/dist/internal/machine/invocation.js +17 -10
  32. package/dist/internal/machine/invocation.js.map +1 -1
  33. package/dist/internal/machine/machine.d.ts +1 -2
  34. package/dist/internal/machine/machine.d.ts.map +1 -1
  35. package/dist/internal/machine/machine.js +21 -6
  36. package/dist/internal/machine/machine.js.map +1 -1
  37. package/dist/internal/machine/planner.d.ts +15 -0
  38. package/dist/internal/machine/planner.d.ts.map +1 -1
  39. package/dist/internal/machine/planner.js +117 -44
  40. package/dist/internal/machine/planner.js.map +1 -1
  41. package/dist/internal/machine/process.d.ts.map +1 -1
  42. package/dist/internal/machine/process.js +4 -2
  43. package/dist/internal/machine/process.js.map +1 -1
  44. package/dist/internal/machine/runtime.d.ts +27 -3
  45. package/dist/internal/machine/runtime.d.ts.map +1 -1
  46. package/dist/internal/machine/runtime.js +440 -64
  47. package/dist/internal/machine/runtime.js.map +1 -1
  48. package/dist/internal/machine/symbols.d.ts +2 -0
  49. package/dist/internal/machine/symbols.d.ts.map +1 -1
  50. package/dist/internal/machine/symbols.js +2 -0
  51. package/dist/internal/machine/symbols.js.map +1 -1
  52. package/dist/internal/machine/topology.d.ts +13 -0
  53. package/dist/internal/machine/topology.d.ts.map +1 -1
  54. package/dist/internal/machine/topology.js +9 -0
  55. package/dist/internal/machine/topology.js.map +1 -1
  56. package/dist/internal/testing/machine/finiteModel.d.ts.map +1 -1
  57. package/dist/internal/testing/machine/finiteModel.js +3 -3
  58. package/dist/internal/testing/machine/finiteModel.js.map +1 -1
  59. package/dist/unstable/reactivity/AtomMachine.d.ts +9 -0
  60. package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
  61. package/dist/unstable/reactivity/AtomMachine.js +9 -0
  62. package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
  63. package/docs/agent-guide.md +102 -9
  64. package/package.json +5 -5
  65. package/src/Machine.ts +505 -174
  66. package/src/internal/machine/atom.ts +26 -0
  67. package/src/internal/machine/commandRuntime.ts +2 -9
  68. package/src/internal/machine/configuration.ts +28 -3
  69. package/src/internal/machine/executionPlan.ts +50 -17
  70. package/src/internal/machine/initialization.ts +73 -0
  71. package/src/internal/machine/inspectionRuntime.ts +102 -0
  72. package/src/internal/machine/invocation.ts +37 -12
  73. package/src/internal/machine/machine.ts +31 -6
  74. package/src/internal/machine/planner.ts +136 -42
  75. package/src/internal/machine/process.ts +4 -2
  76. package/src/internal/machine/runtime.ts +661 -89
  77. package/src/internal/machine/symbols.ts +3 -0
  78. package/src/internal/machine/topology.ts +27 -0
  79. package/src/internal/testing/machine/finiteModel.ts +8 -7
  80. package/src/unstable/reactivity/AtomMachine.ts +12 -0
@@ -33,7 +33,7 @@ import type { EnsureExecutable } from "./readiness.js"
33
33
  import * as internalRuntime from "./runtime.js"
34
34
  import * as Serialization from "./serialization.js"
35
35
  import * as StateDefinition from "./stateDefinition.js"
36
- import { ChildMachineLogicTypeId } from "./symbols.js"
36
+ import { ChildMachineLogicTypeId, SnapshotBuilderStateTypeId } from "./symbols.js"
37
37
  import * as Topology from "./topology.js"
38
38
 
39
39
  export {
@@ -45,10 +45,9 @@ export {
45
45
  StartupError,
46
46
  StoppedError
47
47
  } from "./errors.js"
48
- export { ChildMachineLogicTypeId, InitialEventTypeId } from "./symbols.js"
48
+ export { ChildMachineLogicTypeId, InitialEventTypeId, SnapshotBuilderStateTypeId } from "./symbols.js"
49
49
 
50
50
  const TypeId = "~effect/Machine"
51
- export const SnapshotBuilderStateTypeId: unique symbol = Symbol("effect/Machine/SnapshotBuilderState")
52
51
  export const InvokeTypeId: unique symbol = Symbol.for("effect/Machine/Invoke")
53
52
  const ChildMachineTypeId = "~effect/Machine/ChildMachine"
54
53
  type IsAny<A> = 0 extends 1 & A ? true : false
@@ -300,6 +299,24 @@ const withFrom = <Method extends (value: unknown, ...args: ReadonlyArray<any>) =
300
299
  return method as Method & { readonly from: (...args: ReadonlyArray<any>) => unknown }
301
300
  }
302
301
 
302
+ const withInitial = <Builder extends object>(
303
+ builder: Builder,
304
+ path: string,
305
+ valued: boolean,
306
+ values?: Readonly<Record<string, unknown>>
307
+ ): Builder => {
308
+ const initial = withFrom(
309
+ (value: unknown) => Topology.makeInitialTarget(path, value, values),
310
+ "leaf",
311
+ valued
312
+ )
313
+ Object.defineProperty(builder, "initial", {
314
+ value: initial,
315
+ enumerable: false
316
+ })
317
+ return builder
318
+ }
319
+
303
320
  const makeSnapshotBuilder = (
304
321
  states: Machine.StateTree,
305
322
  options: SnapshotBuilderOptions
@@ -317,12 +334,15 @@ const makeSnapshotBuilder = (
317
334
  continue
318
335
  }
319
336
  const node = Topology.getStateNodeDefinition(path, definition)
320
- builder[key] = withFrom(
337
+ const method = withFrom(
321
338
  (value: unknown, selector?: (builder: unknown) => unknown) =>
322
339
  makeSnapshotForNode(definition, key, value, selector, options),
323
340
  node.states === undefined ? "leaf" : "nested",
324
341
  node.schema !== undefined
325
342
  )
343
+ builder[key] = node.states === undefined || options.mode !== "full" || options.prefix !== ""
344
+ ? method
345
+ : withInitial(method, path, node.schema !== undefined)
326
346
  }
327
347
  return builder
328
348
  }
@@ -348,7 +368,7 @@ const makeParallelSnapshotBuilder = (
348
368
  }
349
369
  const path = options.prefix === "" ? key : `${options.prefix}.${key}`
350
370
  const node = Topology.getStateNodeDefinition(path, definition)
351
- builder[key] = withFrom(
371
+ const method = withFrom(
352
372
  (value: unknown, selector?: (builder: unknown) => unknown) => {
353
373
  const nextRegions: Record<string, unknown> = {}
354
374
  for (const regionKey of Object.keys(regions)) {
@@ -360,6 +380,7 @@ const makeParallelSnapshotBuilder = (
360
380
  node.states === undefined ? "leaf" : "nested",
361
381
  node.schema !== undefined
362
382
  )
383
+ builder[key] = method
363
384
  }
364
385
  return builder
365
386
  }
@@ -538,7 +559,7 @@ const makeLocalTargetChildBuilder = (
538
559
  builder[child.key] = () => Topology.makeChoiceTarget(child.path, parent.path, values)
539
560
  continue
540
561
  }
541
- builder[child.key] = withFrom(
562
+ const method = withFrom(
542
563
  (value: unknown, selector?: (builder: unknown) => unknown) => {
543
564
  if (child.type === "atomic" || child.type === "final") {
544
565
  return makeTargetWithValues(child.path, value, values)
@@ -572,6 +593,9 @@ const makeLocalTargetChildBuilder = (
572
593
  child.type === "atomic" || child.type === "final" ? "leaf" : "nested",
573
594
  child.schema !== undefined
574
595
  )
596
+ builder[child.key] = child.type === "atomic" || child.type === "final"
597
+ ? method
598
+ : withInitial(method, child.path, child.schema !== undefined, values)
575
599
  }
576
600
  return builder
577
601
  }
@@ -677,6 +701,7 @@ const makeBranchTargetNodeBuilder = (
677
701
  "nested",
678
702
  node.schema !== undefined
679
703
  ) as unknown as Record<string, unknown>
704
+ withInitial(builder, node.path, node.schema !== undefined, values)
680
705
  if (node.type !== "parallel" || source === node.path || source.startsWith(`${node.path}.`)) {
681
706
  addBranchTargetChildren(builder, states, stateNodes, node.path, values, source)
682
707
  }
@@ -22,6 +22,7 @@ import {
22
22
  completeConfigurationEffect,
23
23
  completeConfigurationSync,
24
24
  configurationFromHistoryRecord,
25
+ configurationFromInitialTargetSync,
25
26
  getActiveLeafPathFrom,
26
27
  getActiveLeafPaths,
27
28
  getHistoryRecord,
@@ -44,13 +45,16 @@ import {
44
45
  validateInitialConfiguration
45
46
  } from "./configuration.js"
46
47
  import { InfiniteTransitionError, MachineSchemaDecodeError, StartupError, StoppedError } from "./errors.js"
48
+ import { getStateInitializeValues, makeStateInitializeBuilder } from "./initialization.js"
47
49
  import * as InvocationEvent from "./invocationEvent.js"
48
50
  import { decodeEventSync, decodeInputSync, decodeStateValueSync } from "./protocol.js"
49
51
  import { InitialEventTypeId } from "./symbols.js"
50
52
  import {
51
53
  getNode,
54
+ type InitialTarget as InitialTargetInstruction,
52
55
  isChoiceTarget,
53
56
  isHistoryTarget,
57
+ isInitialTarget,
54
58
  isNoTarget,
55
59
  isSnapshot,
56
60
  isTarget,
@@ -230,6 +234,7 @@ const completeHistoryConfiguration = (
230
234
  const commands: Array<RuntimeCommand> = []
231
235
  const raisedEvents: Array<unknown> = []
232
236
  const emittedEvents: Array<unknown> = []
237
+ const transitions: Array<ResolvedChoiceTransition> = []
233
238
 
234
239
  let changed = true
235
240
  while (changed) {
@@ -248,9 +253,47 @@ const completeHistoryConfiguration = (
248
253
  history: configuration.history,
249
254
  machineReferences: configuration.machineReferences
250
255
  } as ActiveConfiguration
256
+ if (child.type === "choice") {
257
+ const choice = resolveChoiceTarget(
258
+ machine,
259
+ current,
260
+ makeChoiceTarget(child.path, path, Object.fromEntries(values)),
261
+ event
262
+ )
263
+ let next = current
264
+ for (const routed of [choice.target, ...choice.additionalTargets]) {
265
+ if (routed === undefined || isHistoryTarget(routed)) {
266
+ throw new Error(`Machine initial choice "${child.path}" must resolve to an active state target`)
267
+ }
268
+ const resolved = isInitialTarget(routed)
269
+ ? resolveInitialTarget(machine, next, routed, event)
270
+ : undefined
271
+ next = normalizeTargetConfigurationSync(
272
+ machine,
273
+ next,
274
+ (resolved?.target ?? routed) as Machine.Snapshot<any> | Machine.Target<any, any>
275
+ )
276
+ if (resolved !== undefined) {
277
+ commands.push(...resolved.commands)
278
+ raisedEvents.push(...resolved.raisedEvents)
279
+ emittedEvents.push(...resolved.emittedEvents)
280
+ transitions.push(...resolved.transitions)
281
+ }
282
+ }
283
+ active.clear()
284
+ values.clear()
285
+ for (const activePath of next.active) active.add(activePath)
286
+ for (const [valuePath, stateValue] of next.values) values.set(valuePath, stateValue)
287
+ commands.push(...choice.commands)
288
+ raisedEvents.push(...choice.raisedEvents)
289
+ emittedEvents.push(...choice.emittedEvents)
290
+ transitions.push(...choice.transitions)
291
+ changed = true
292
+ continue
293
+ }
251
294
  active.add(child.path)
252
295
  if (child.schema !== undefined) {
253
- const initializer = machine.handlers[path]?.initial
296
+ const initializer = machine.handlers[path]?.initialize
254
297
  if (initializer === undefined) {
255
298
  throw new Error(`Machine shallow history requires an initial value implementation for state "${path}"`)
256
299
  }
@@ -259,9 +302,11 @@ const completeHistoryConfiguration = (
259
302
  state: current.values.get(path),
260
303
  containingState: getParentValue(machine, current, path),
261
304
  ancestors: getParentValues(machine, current, path),
262
- event
305
+ event,
306
+ builder: makeStateInitializeBuilder(machine, path)
263
307
  })
264
- values.set(child.path, decodeStateValueSync(machine, child, initialized.value))
308
+ const initializedValues = getStateInitializeValues(path, initialized.value)
309
+ values.set(child.path, decodeStateValueSync(machine, child, initializedValues[child.key]))
265
310
  commands.push(...initialized.commands)
266
311
  raisedEvents.push(...initialized.raisedEvents)
267
312
  emittedEvents.push(...initialized.emittedEvents)
@@ -279,7 +324,7 @@ const completeHistoryConfiguration = (
279
324
  history: configuration.history,
280
325
  machineReferences: configuration.machineReferences
281
326
  } as ActiveConfiguration
282
- const initializer = valuedMissing.length === 0 ? undefined : machine.handlers[path]?.initial
327
+ const initializer = valuedMissing.length === 0 ? undefined : machine.handlers[path]?.initialize
283
328
  if (valuedMissing.length > 0 && initializer === undefined) {
284
329
  throw new Error(`Machine shallow history requires an initial value implementation for state "${path}"`)
285
330
  }
@@ -288,24 +333,25 @@ const completeHistoryConfiguration = (
288
333
  state: current.values.get(path),
289
334
  containingState: getParentValue(machine, current, path),
290
335
  ancestors: getParentValues(machine, current, path),
291
- event
336
+ event,
337
+ builder: makeStateInitializeBuilder(machine, path)
292
338
  })
293
- if (initialized !== undefined && (typeof initialized.value !== "object" || initialized.value === null)) {
294
- throw new Error(`Machine parallel state initializer for "${path}" must return its region values`)
295
- }
339
+ const initializedValues = initialized === undefined
340
+ ? undefined
341
+ : getStateInitializeValues(path, initialized.value)
296
342
  for (const childPath of missing) {
297
343
  const child = getNode(machine, childPath)
298
344
  active.add(child.path)
299
345
  if (child.schema !== undefined) {
300
346
  if (
301
347
  initialized === undefined ||
302
- !Object.prototype.hasOwnProperty.call(initialized.value as object, child.key)
348
+ initializedValues === undefined || !Object.prototype.hasOwnProperty.call(initializedValues, child.key)
303
349
  ) {
304
350
  throw new Error(`Machine parallel state initializer for "${path}" must return region "${child.key}"`)
305
351
  }
306
352
  values.set(
307
353
  child.path,
308
- decodeStateValueSync(machine, child, (initialized.value as Record<string, unknown>)[child.key])
354
+ decodeStateValueSync(machine, child, initializedValues[child.key])
309
355
  )
310
356
  }
311
357
  }
@@ -328,16 +374,38 @@ const completeHistoryConfiguration = (
328
374
  } as ActiveConfiguration,
329
375
  commands,
330
376
  raisedEvents,
331
- emittedEvents
377
+ emittedEvents,
378
+ transitions
332
379
  }
333
380
  }
334
381
 
335
- const resolveHistoryTarget = (
382
+ export function resolveInitialTarget(
383
+ machine: Machine.Any,
384
+ configuration: ActiveConfiguration,
385
+ target: InitialTargetInstruction,
386
+ event: unknown
387
+ ) {
388
+ const partial = configurationFromInitialTargetSync(machine, configuration, target)
389
+ const completed = completeHistoryConfiguration(machine, partial, event)
390
+ const snapshot = snapshotFromConfigurationAtPath(machine, completed.configuration, target.path)
391
+ return {
392
+ target: makeTarget(target.path as any, snapshot.value as any, {
393
+ snapshot: snapshot as any,
394
+ values: Object.fromEntries(completed.configuration.values) as any
395
+ }),
396
+ commands: completed.commands,
397
+ raisedEvents: completed.raisedEvents,
398
+ emittedEvents: completed.emittedEvents,
399
+ transitions: completed.transitions
400
+ }
401
+ }
402
+
403
+ function resolveHistoryTarget(
336
404
  machine: Machine.Any,
337
405
  configuration: ActiveConfiguration,
338
406
  target: { readonly path: string; readonly parent: string },
339
407
  event: unknown
340
- ) => {
408
+ ) {
341
409
  const node = getNode(machine, target.path)
342
410
  if (node.type !== "history" || node.parent !== target.parent) {
343
411
  throw new Error(`Machine expected history target "${target.path}" to resolve to its declared parent`)
@@ -359,7 +427,7 @@ const resolveHistoryTarget = (
359
427
  commands: completed.commands,
360
428
  raisedEvents: completed.raisedEvents,
361
429
  emittedEvents: completed.emittedEvents,
362
- transitions: []
430
+ transitions: completed.transitions
363
431
  }
364
432
  }
365
433
 
@@ -1065,12 +1133,12 @@ interface ResolvedChoiceTransition {
1065
1133
  readonly resolvedTarget: string
1066
1134
  }
1067
1135
 
1068
- const resolveChoiceTarget = (
1136
+ function resolveChoiceTarget(
1069
1137
  machine: Machine.Any,
1070
1138
  configuration: ActiveConfiguration,
1071
1139
  initialTarget: unknown,
1072
1140
  event: unknown
1073
- ) => {
1141
+ ) {
1074
1142
  const pending: Array<unknown> = [initialTarget]
1075
1143
  const resolvedTargets: Array<unknown> = []
1076
1144
  const commands: Array<RuntimeCommand> = []
@@ -1141,7 +1209,7 @@ const resolveChoiceTarget = (
1141
1209
  emittedEvents.push(...collected.emittedEvents)
1142
1210
  }
1143
1211
 
1144
- if (!isTarget(current) && !isSnapshot(current) && !isHistoryTarget(current)) {
1212
+ if (!isTarget(current) && !isSnapshot(current) && !isHistoryTarget(current) && !isInitialTarget(current)) {
1145
1213
  throw new Error("Machine choice resolver must return a concrete typed target")
1146
1214
  }
1147
1215
  resolvedTargets.push(current)
@@ -1196,6 +1264,10 @@ const collectEvaluatedTransition = <
1196
1264
  (selection.context as any).event
1197
1265
  )
1198
1266
  const choiceResolvedTarget = choiceResolution?.target ?? unresolvedTarget
1267
+ const initialResolution = choiceResolvedTarget !== undefined && isInitialTarget(choiceResolvedTarget)
1268
+ ? resolveInitialTarget(machine, state, choiceResolvedTarget, (selection.context as any).event)
1269
+ : undefined
1270
+ const routedTarget = initialResolution?.target ?? choiceResolvedTarget
1199
1271
  let historyResolution: {
1200
1272
  readonly target: unknown
1201
1273
  readonly commands: ReadonlyArray<RuntimeCommand>
@@ -1203,50 +1275,64 @@ const collectEvaluatedTransition = <
1203
1275
  readonly emittedEvents: ReadonlyArray<unknown>
1204
1276
  readonly transitions: ReadonlyArray<ResolvedChoiceTransition>
1205
1277
  } | undefined
1206
- const reenteredHistoryTarget = isHistoryTarget(choiceResolvedTarget) && selection.transition.reenter &&
1207
- state.active.has(choiceResolvedTarget.parent)
1208
- ? choiceResolvedTarget
1278
+ const reenteredHistoryTarget = isHistoryTarget(routedTarget) && selection.transition.reenter &&
1279
+ state.active.has(routedTarget.parent)
1280
+ ? routedTarget
1209
1281
  : undefined
1210
- if (choiceResolvedTarget !== undefined && isHistoryTarget(choiceResolvedTarget)) {
1282
+ if (routedTarget !== undefined && isHistoryTarget(routedTarget)) {
1211
1283
  // A reentering transition may exit the history node's own parent. SCXML
1212
1284
  // history observes that same exit, so resolve against a provisional
1213
1285
  // capture rather than an older record (or the default).
1214
1286
  const provisionalBoundary = selection.transition.reenter
1215
1287
  ? getNode(machine, selection.sourcePath).parent
1216
- : getLeastCommonAncestor(machine, stateIdentifier, choiceResolvedTarget.parent)
1288
+ : getLeastCommonAncestor(machine, stateIdentifier, routedTarget.parent)
1217
1289
  const provisionalExitPaths = reenteredHistoryTarget !== undefined
1218
1290
  ? sortExitPaths(
1219
1291
  machine,
1220
- Array.from(state.active).filter((path) => isPathInSubtree(path, choiceResolvedTarget.parent))
1292
+ Array.from(state.active).filter((path) => isPathInSubtree(path, routedTarget.parent))
1221
1293
  )
1222
1294
  : getExitPaths(machine, state, provisionalBoundary)
1223
- const stateAtHistoryResolution = provisionalExitPaths.includes(choiceResolvedTarget.parent)
1295
+ const stateAtHistoryResolution = provisionalExitPaths.includes(routedTarget.parent)
1224
1296
  ? captureHistory(machine, state, state, provisionalExitPaths)
1225
1297
  : state
1226
1298
  historyResolution = resolveHistoryTarget(
1227
1299
  machine,
1228
1300
  stateAtHistoryResolution,
1229
- choiceResolvedTarget,
1301
+ routedTarget,
1230
1302
  (selection.context as any).event
1231
1303
  )
1232
1304
  }
1233
1305
  const target: Machine.Snapshot<States> | Machine.Target<States, Machine.StateIdentifier<States>> | undefined =
1234
1306
  historyResolution === undefined
1235
- ? choiceResolvedTarget as
1307
+ ? routedTarget as
1236
1308
  | Machine.Snapshot<States>
1237
1309
  | Machine.Target<States, Machine.StateIdentifier<States>>
1238
1310
  | undefined
1239
1311
  : historyResolution.target as
1240
1312
  | Machine.Snapshot<States>
1241
1313
  | Machine.Target<States, Machine.StateIdentifier<States>>
1242
- const additionalHistoryActions: Array<RuntimeCommand> = []
1243
- const additionalHistoryRaisedEvents: Array<unknown> = []
1244
- const additionalHistoryEmittedEvents: Array<unknown> = []
1245
- const additionalHistoryChoiceTransitions: Array<ResolvedChoiceTransition> = []
1314
+ const additionalTargetActions: Array<RuntimeCommand> = []
1315
+ const additionalTargetRaisedEvents: Array<unknown> = []
1316
+ const additionalTargetEmittedEvents: Array<unknown> = []
1317
+ const additionalTargetChoiceTransitions: Array<ResolvedChoiceTransition> = []
1246
1318
  const additionalChoiceTargets: Array<
1247
1319
  Machine.Snapshot<States> | Machine.Target<States, Machine.StateIdentifier<States>>
1248
1320
  > = []
1249
1321
  for (const additionalTarget of choiceResolution?.additionalTargets ?? []) {
1322
+ if (isInitialTarget(additionalTarget)) {
1323
+ const resolved = resolveInitialTarget(
1324
+ machine,
1325
+ state,
1326
+ additionalTarget,
1327
+ (selection.context as any).event
1328
+ )
1329
+ additionalChoiceTargets.push(resolved.target as any)
1330
+ additionalTargetActions.push(...resolved.commands)
1331
+ additionalTargetRaisedEvents.push(...resolved.raisedEvents)
1332
+ additionalTargetEmittedEvents.push(...resolved.emittedEvents)
1333
+ additionalTargetChoiceTransitions.push(...resolved.transitions)
1334
+ continue
1335
+ }
1250
1336
  if (!isHistoryTarget(additionalTarget)) {
1251
1337
  additionalChoiceTargets.push(additionalTarget as any)
1252
1338
  continue
@@ -1258,10 +1344,10 @@ const collectEvaluatedTransition = <
1258
1344
  (selection.context as any).event
1259
1345
  )
1260
1346
  additionalChoiceTargets.push(resolved.target as any)
1261
- additionalHistoryActions.push(...resolved.commands)
1262
- additionalHistoryRaisedEvents.push(...resolved.raisedEvents)
1263
- additionalHistoryEmittedEvents.push(...resolved.emittedEvents)
1264
- additionalHistoryChoiceTransitions.push(...resolved.transitions)
1347
+ additionalTargetActions.push(...resolved.commands)
1348
+ additionalTargetRaisedEvents.push(...resolved.raisedEvents)
1349
+ additionalTargetEmittedEvents.push(...resolved.emittedEvents)
1350
+ additionalTargetChoiceTransitions.push(...resolved.transitions)
1265
1351
  }
1266
1352
  const targetPath = target === undefined
1267
1353
  ? undefined
@@ -1288,28 +1374,32 @@ const collectEvaluatedTransition = <
1288
1374
  commands: [
1289
1375
  ...transitionResult.commands,
1290
1376
  ...(choiceResolution?.commands ?? []),
1377
+ ...(initialResolution?.commands ?? []),
1291
1378
  ...(historyResolution?.commands ?? []),
1292
- ...additionalHistoryActions
1379
+ ...additionalTargetActions
1293
1380
  ],
1294
1381
  raisedEvents: [
1295
1382
  ...transitionResult.raisedEvents,
1296
1383
  ...(choiceResolution?.raisedEvents ?? []),
1384
+ ...(initialResolution?.raisedEvents ?? []),
1297
1385
  ...(historyResolution?.raisedEvents ?? []),
1298
- ...additionalHistoryRaisedEvents
1386
+ ...additionalTargetRaisedEvents
1299
1387
  ],
1300
1388
  emittedEvents: [
1301
1389
  ...transitionResult.emittedEvents,
1302
1390
  ...(choiceResolution?.emittedEvents ?? []),
1391
+ ...(initialResolution?.emittedEvents ?? []),
1303
1392
  ...(historyResolution?.emittedEvents ?? []),
1304
- ...additionalHistoryEmittedEvents
1393
+ ...additionalTargetEmittedEvents
1305
1394
  ],
1306
1395
  changed,
1307
1396
  exitPaths: [],
1308
1397
  entryPaths: [],
1309
1398
  choiceTransitions: [
1310
1399
  ...(choiceResolution?.transitions ?? []),
1400
+ ...(initialResolution?.transitions ?? []),
1311
1401
  ...(historyResolution?.transitions ?? []),
1312
- ...additionalHistoryChoiceTransitions
1402
+ ...additionalTargetChoiceTransitions
1313
1403
  ]
1314
1404
  } as EvaluatedTransition<States, Event, E, R, Context>
1315
1405
  }
@@ -1329,20 +1419,23 @@ const collectEvaluatedTransition = <
1329
1419
  commands: [
1330
1420
  ...transitionResult.commands,
1331
1421
  ...(choiceResolution?.commands ?? []),
1422
+ ...(initialResolution?.commands ?? []),
1332
1423
  ...(historyResolution?.commands ?? []),
1333
- ...additionalHistoryActions
1424
+ ...additionalTargetActions
1334
1425
  ],
1335
1426
  raisedEvents: [
1336
1427
  ...transitionResult.raisedEvents,
1337
1428
  ...(choiceResolution?.raisedEvents ?? []),
1429
+ ...(initialResolution?.raisedEvents ?? []),
1338
1430
  ...(historyResolution?.raisedEvents ?? []),
1339
- ...additionalHistoryRaisedEvents
1431
+ ...additionalTargetRaisedEvents
1340
1432
  ],
1341
1433
  emittedEvents: [
1342
1434
  ...transitionResult.emittedEvents,
1343
1435
  ...(choiceResolution?.emittedEvents ?? []),
1436
+ ...(initialResolution?.emittedEvents ?? []),
1344
1437
  ...(historyResolution?.emittedEvents ?? []),
1345
- ...additionalHistoryEmittedEvents
1438
+ ...additionalTargetEmittedEvents
1346
1439
  ],
1347
1440
  changed,
1348
1441
  exitPaths: reenteredHistoryTarget !== undefined
@@ -1359,8 +1452,9 @@ const collectEvaluatedTransition = <
1359
1452
  : getEntryPaths(machine, stateAfterTransition, boundary),
1360
1453
  choiceTransitions: [
1361
1454
  ...(choiceResolution?.transitions ?? []),
1455
+ ...(initialResolution?.transitions ?? []),
1362
1456
  ...(historyResolution?.transitions ?? []),
1363
- ...additionalHistoryChoiceTransitions
1457
+ ...additionalTargetChoiceTransitions
1364
1458
  ]
1365
1459
  } as EvaluatedTransition<States, Event, E, R, Context>
1366
1460
  }
@@ -73,8 +73,7 @@ const acknowledgedPlan = (
73
73
  commands: planned.commands,
74
74
  emittedEvents: planned.emittedEvents,
75
75
  microsteps: planned.microsteps.map((microstep) => {
76
- const { transitions: _, ...evidence } = microstep
77
- return { ...evidence, next: snapshot(microstep.next) }
76
+ return { ...microstep, transitions: microstep.transitions ?? [], next: snapshot(microstep.next) }
78
77
  }),
79
78
  done: planned.done,
80
79
  output: planned.output
@@ -433,6 +432,7 @@ const makeProcessLogic: <
433
432
  ) => {
434
433
  try {
435
434
  const planned = compiledInitial(initialArgs, scope)
435
+ scope.inspectInitial(planned.initialEntryPaths)
436
436
  const result = {
437
437
  state: planned.state as Machine.Snapshot<States>,
438
438
  done: planned.done,
@@ -461,6 +461,7 @@ const makeProcessLogic: <
461
461
  ? internalRuntime.provideMachineRuntime(
462
462
  internalPlanner.planInitial(internalPlanner.withMachineReferences(machine, scope), ...initialArgs).pipe(
463
463
  Effect.flatMap((planned) => {
464
+ scope.inspectInitial(planned.initialEntryPaths, planned.microsteps)
464
465
  const commands = planned.commands.length === 0
465
466
  ? undefined
466
467
  : CommandRuntime.runCommands(planned.commands, scope)
@@ -486,6 +487,7 @@ const makeProcessLogic: <
486
487
  )
487
488
  : Effect.try({ try: () => makeCompiledInitial!(scope), catch: (error) => error as any })
488
489
  return ({
490
+ inspection: { kind: "Machine", definition: machine },
489
491
  execution: {
490
492
  _tag: "Compiled",
491
493
  childless: !hasInvokes,