@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.
- package/README.md +4 -3
- package/dist/Machine.d.ts +24 -6
- package/dist/Machine.d.ts.map +1 -1
- package/dist/Machine.js.map +1 -1
- package/dist/internal/machine/atom.d.ts +5 -0
- package/dist/internal/machine/atom.d.ts.map +1 -1
- package/dist/internal/machine/atom.js +6 -3
- package/dist/internal/machine/atom.js.map +1 -1
- package/dist/internal/machine/machine.d.ts.map +1 -1
- package/dist/internal/machine/machine.js +1 -1
- package/dist/internal/machine/machine.js.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.d.ts +26 -0
- package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -1
- package/dist/unstable/reactivity/AtomMachine.js +23 -0
- package/dist/unstable/reactivity/AtomMachine.js.map +1 -1
- package/docs/agent-guide.md +14 -0
- package/package.json +5 -5
- package/src/Machine.ts +6909 -0
- package/src/index.ts +1 -0
- package/src/internal/machine/activities.ts +108 -0
- package/src/internal/machine/atom.ts +684 -0
- package/src/internal/machine/cluster.ts +394 -0
- package/src/internal/machine/command.ts +58 -0
- package/src/internal/machine/commandRuntime.ts +43 -0
- package/src/internal/machine/configuration.ts +1331 -0
- package/src/internal/machine/errors.ts +87 -0
- package/src/internal/machine/executionPlan.ts +996 -0
- package/src/internal/machine/invocation.ts +119 -0
- package/src/internal/machine/machine.ts +1750 -0
- package/src/internal/machine/planner.ts +1933 -0
- package/src/internal/machine/process.ts +906 -0
- package/src/internal/machine/protocol.ts +322 -0
- package/src/internal/machine/readiness.ts +10 -0
- package/src/internal/machine/runtime.ts +2512 -0
- package/src/internal/machine/serialization.ts +498 -0
- package/src/internal/machine/stateDefinition.ts +270 -0
- package/src/internal/machine/symbols.ts +2 -0
- package/src/internal/machine/topology.ts +479 -0
- package/src/internal/testing/machine/arbitrary.ts +102 -0
- package/src/internal/testing/machine/exploration.ts +331 -0
- package/src/internal/testing/machine/finiteModel.ts +1498 -0
- package/src/internal/testing/machine/invariant.ts +372 -0
- package/src/internal/testing/machine/probe.ts +79 -0
- package/src/internal/testing/machine/referenceModel.ts +1505 -0
- package/src/internal/testing/machine/runtime.ts +1710 -0
- package/src/internal/testing/machine/runtimeInvariant.ts +486 -0
- package/src/internal/testing/machine/trace.ts +150 -0
- package/src/internal/testing/machine/verification.ts +1890 -0
- package/src/testing/MachineTest.ts +2067 -0
- package/src/testing/index.ts +7 -0
- package/src/unstable/cluster/ClusterMachine.ts +390 -0
- package/src/unstable/cluster/index.ts +1 -0
- package/src/unstable/reactivity/AtomMachine.ts +696 -0
- package/src/unstable/reactivity/index.ts +1 -0
|
@@ -0,0 +1,1750 @@
|
|
|
1
|
+
import * as Duration from "effect/Duration"
|
|
2
|
+
import * as Effect from "effect/Effect"
|
|
3
|
+
import * as Inspectable from "effect/Inspectable"
|
|
4
|
+
import * as Option from "effect/Option"
|
|
5
|
+
import { Prototype as PipeablePrototype } from "effect/Pipeable"
|
|
6
|
+
import { hasProperty } from "effect/Predicate"
|
|
7
|
+
import type * as Schema from "effect/Schema"
|
|
8
|
+
import type * as Scope from "effect/Scope"
|
|
9
|
+
import type * as Stream from "effect/Stream"
|
|
10
|
+
import type {
|
|
11
|
+
ActionError,
|
|
12
|
+
ChildAddress,
|
|
13
|
+
ChildMachine,
|
|
14
|
+
Command,
|
|
15
|
+
ExecutionServices,
|
|
16
|
+
InitialEvent as InitialEventModel,
|
|
17
|
+
Logic,
|
|
18
|
+
Machine,
|
|
19
|
+
MachineRef,
|
|
20
|
+
MachineSchemaDecodeError,
|
|
21
|
+
MachineSchemaEncodeError,
|
|
22
|
+
Runtime,
|
|
23
|
+
RuntimeOutcome,
|
|
24
|
+
SpawnOptions,
|
|
25
|
+
StoppedError
|
|
26
|
+
} from "../../Machine.js"
|
|
27
|
+
import * as Activities from "./activities.js"
|
|
28
|
+
import * as Configuration from "./configuration.js"
|
|
29
|
+
import type { ChildAlreadyExistsError, InfiniteTransitionError, StartupError } from "./errors.js"
|
|
30
|
+
import * as internalPlanner from "./planner.js"
|
|
31
|
+
import * as internalProcess from "./process.js"
|
|
32
|
+
import * as Protocol from "./protocol.js"
|
|
33
|
+
import type { EnsureExecutable } from "./readiness.js"
|
|
34
|
+
import * as internalRuntime from "./runtime.js"
|
|
35
|
+
import * as Serialization from "./serialization.js"
|
|
36
|
+
import * as StateDefinition from "./stateDefinition.js"
|
|
37
|
+
import * as Topology from "./topology.js"
|
|
38
|
+
|
|
39
|
+
export {
|
|
40
|
+
ChildAlreadyExistsError,
|
|
41
|
+
InfiniteTransitionError,
|
|
42
|
+
MachineSchemaDecodeError,
|
|
43
|
+
MachineSchemaEncodeError,
|
|
44
|
+
ProcessLocalError,
|
|
45
|
+
StartupError,
|
|
46
|
+
StoppedError
|
|
47
|
+
} from "./errors.js"
|
|
48
|
+
export { InitialEventTypeId } from "./symbols.js"
|
|
49
|
+
|
|
50
|
+
const TypeId = "~effect/Machine"
|
|
51
|
+
export const SnapshotBuilderStateTypeId: unique symbol = Symbol("effect/Machine/SnapshotBuilderState")
|
|
52
|
+
export const InvokeTypeId: unique symbol = Symbol.for("effect/Machine/Invoke")
|
|
53
|
+
const ChildMachineTypeId = "~effect/Machine/ChildMachine"
|
|
54
|
+
type InvokeLifecycleId = string
|
|
55
|
+
type IsAny<A> = 0 extends 1 & A ? true : false
|
|
56
|
+
type MachineRuntimeRequirement = internalRuntime.MachineRuntime
|
|
57
|
+
type ExcludeCompatibleRuntime<Requirements, Events, Emits> = Requirements extends Runtime.Requirement<
|
|
58
|
+
infer RequiredEvents,
|
|
59
|
+
infer RequiredEmits
|
|
60
|
+
> ? IsAny<Requirements> extends true ? Requirements
|
|
61
|
+
: [RequiredEvents] extends [Events] ? [RequiredEmits] extends [Emits] ? never : Requirements
|
|
62
|
+
: Requirements
|
|
63
|
+
: Requirements
|
|
64
|
+
type SpawnRequirements<Requirements> = Exclude<Requirements, Scope.Scope>
|
|
65
|
+
type SpawnIdError<Options extends SpawnOptions> = "id" extends keyof Options ? Options extends {
|
|
66
|
+
readonly id?: infer Id
|
|
67
|
+
} ? [Id] extends [undefined] ? never : ChildAlreadyExistsError
|
|
68
|
+
: ChildAlreadyExistsError
|
|
69
|
+
: never
|
|
70
|
+
type SpawnError<Options extends SpawnOptions> = SpawnIdError<Options>
|
|
71
|
+
type SpawnResult<State, Event, Error, Requirements, Output, SpawnError, InitialError = never> = Effect.Effect<
|
|
72
|
+
MachineRef<State, Event, Error, Output>,
|
|
73
|
+
SpawnError | InitialError,
|
|
74
|
+
MachineRuntimeRequirement | SpawnRequirements<Requirements>
|
|
75
|
+
>
|
|
76
|
+
type DefineStateTreeInput<States extends Machine.StateSchemas> = States
|
|
77
|
+
type ValidateDefinedStates<States extends Machine.StateSchemas> = [States] extends
|
|
78
|
+
[Machine.ValidateStateSchemas<States>] ? []
|
|
79
|
+
: [validation: Machine.ValidateStateSchemas<States>]
|
|
80
|
+
type InvalidDefinedStateTreeInput<States extends Machine.StateSchemas> = [States] extends
|
|
81
|
+
[Machine.ValidateStateSchemas<States>] ? never
|
|
82
|
+
: States & Machine.ValidateStateSchemas<States>
|
|
83
|
+
interface DefineStates {
|
|
84
|
+
<const States extends Machine.StateSchemas>(
|
|
85
|
+
states: States,
|
|
86
|
+
..._validation: ValidateDefinedStates<NoInfer<States>>
|
|
87
|
+
): Machine.DefinedStates<States>
|
|
88
|
+
<const States extends Machine.StateSchemas>(states: InvalidDefinedStateTreeInput<States>): never
|
|
89
|
+
}
|
|
90
|
+
type ValidateInputEventProtocol<InputEvents extends ReadonlyArray<Machine.TaggedSchema>> = InputEvents
|
|
91
|
+
type ValidateInternalEventProtocol<
|
|
92
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
|
|
93
|
+
InternalEvents extends ReadonlyArray<Machine.TaggedSchema>
|
|
94
|
+
> = InputEvents | InternalEvents extends ReadonlyArray<Machine.TaggedSchema> ? unknown : never
|
|
95
|
+
|
|
96
|
+
const Proto = {
|
|
97
|
+
...Inspectable.BaseProto,
|
|
98
|
+
...PipeablePrototype,
|
|
99
|
+
[TypeId]: TypeId,
|
|
100
|
+
toJSON() {
|
|
101
|
+
return {
|
|
102
|
+
_id: "Machine"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const cloneWithHandlers = (
|
|
108
|
+
self: Machine.Any,
|
|
109
|
+
handlers: Machine.StateConfigs<any, any, any, any, any, any, any>
|
|
110
|
+
): Machine.Any => {
|
|
111
|
+
const machine = Object.create(Proto)
|
|
112
|
+
machine.states = self.states
|
|
113
|
+
machine.events = self.events
|
|
114
|
+
machine.internalEvents = self.internalEvents
|
|
115
|
+
machine.emits = self.emits
|
|
116
|
+
machine.input = self.input
|
|
117
|
+
machine.id = self.id
|
|
118
|
+
machine.initial = self.initial
|
|
119
|
+
machine.stateNodes = self.stateNodes
|
|
120
|
+
machine.makeTargetBuilder = self.makeTargetBuilder
|
|
121
|
+
machine.handlers = handlers
|
|
122
|
+
machine.handle = makeHandle(machine)
|
|
123
|
+
Protocol.copyProtocol(self, machine)
|
|
124
|
+
return machine
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const validateTransitionTargets = (
|
|
128
|
+
stateNodes: Machine.StateNodes,
|
|
129
|
+
path: string,
|
|
130
|
+
trigger: PropertyKey,
|
|
131
|
+
transition: unknown
|
|
132
|
+
): void => {
|
|
133
|
+
if (typeof transition !== "object" || transition === null || !hasProperty(transition, "targets")) {
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
if (!Array.isArray(transition.targets)) {
|
|
137
|
+
throw new Error(
|
|
138
|
+
`Machine expected transition targets for state "${path}" on "${String(trigger)}" to be an array`
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
for (const target of transition.targets) {
|
|
142
|
+
if (typeof target !== "string" || !stateNodes.byPath.has(target)) {
|
|
143
|
+
throw new Error(
|
|
144
|
+
`Machine transition for state "${path}" on "${String(trigger)}" declares unknown target "${String(target)}"`
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const captureTransition = (transition: unknown): unknown => {
|
|
151
|
+
if (typeof transition !== "object" || transition === null) {
|
|
152
|
+
return transition
|
|
153
|
+
}
|
|
154
|
+
const captured = { ...(transition as Record<PropertyKey, unknown>) }
|
|
155
|
+
if (Array.isArray(captured.targets)) {
|
|
156
|
+
captured.targets = captured.targets.slice()
|
|
157
|
+
}
|
|
158
|
+
return captured
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const captureEventHandlers = (on: object): Record<PropertyKey, unknown> => {
|
|
162
|
+
// The machine owns its dispatch table. Compiled plans may snapshot these
|
|
163
|
+
// definitions, so retaining caller-owned containers would let strategies
|
|
164
|
+
// observe different handlers after an unsafe external mutation.
|
|
165
|
+
const captured: Record<PropertyKey, unknown> = Object.create(null)
|
|
166
|
+
for (const event of Reflect.ownKeys(on)) {
|
|
167
|
+
captured[event] = captureTransition((on as Record<PropertyKey, unknown>)[event])
|
|
168
|
+
}
|
|
169
|
+
return captured
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const flattenHandlers = (
|
|
173
|
+
handlers: Record<PropertyKey, Machine.AnyStateConfig>,
|
|
174
|
+
stateNodes: Machine.StateNodes,
|
|
175
|
+
states: Machine.StateTree,
|
|
176
|
+
prefix: string,
|
|
177
|
+
config: Record<string, unknown>
|
|
178
|
+
): void => {
|
|
179
|
+
for (const key of Object.keys(config)) {
|
|
180
|
+
const path = prefix === "" ? key : `${prefix}.${key}`
|
|
181
|
+
if (!hasProperty(states, key)) {
|
|
182
|
+
throw new Error(`Machine received handler for unknown state "${path}"`)
|
|
183
|
+
}
|
|
184
|
+
const nodeConfig = config[key]
|
|
185
|
+
if (typeof nodeConfig !== "object" || nodeConfig === null) {
|
|
186
|
+
throw new Error(`Machine expected state "${path}" handler to be an object`)
|
|
187
|
+
}
|
|
188
|
+
const { states: childConfig, ...stateConfig } = nodeConfig as Record<string, unknown>
|
|
189
|
+
const on = stateConfig.on
|
|
190
|
+
if (typeof on === "object" && on !== null) {
|
|
191
|
+
const capturedOn = captureEventHandlers(on)
|
|
192
|
+
stateConfig.on = capturedOn
|
|
193
|
+
for (const event of Reflect.ownKeys(capturedOn)) {
|
|
194
|
+
validateTransitionTargets(stateNodes, path, event, capturedOn[event])
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
validateTransitionTargets(stateNodes, path, "always", stateConfig.always)
|
|
198
|
+
validateTransitionTargets(stateNodes, path, "done", stateConfig.onDone)
|
|
199
|
+
validateTransitionTargets(stateNodes, path, "choice", stateConfig.choice)
|
|
200
|
+
const node = stateNodes.byPath.get(path)
|
|
201
|
+
if (node?.type === "choice") {
|
|
202
|
+
if (
|
|
203
|
+
typeof stateConfig.choice !== "object" || stateConfig.choice === null ||
|
|
204
|
+
!hasProperty(stateConfig.choice, "transition") || typeof stateConfig.choice.transition !== "function" ||
|
|
205
|
+
!hasProperty(stateConfig.choice, "targets") || !Array.isArray(stateConfig.choice.targets) ||
|
|
206
|
+
stateConfig.choice.targets.length === 0
|
|
207
|
+
) {
|
|
208
|
+
throw new Error(`Machine choice state "${path}" requires a transition and at least one declared target`)
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
handlers[path] = stateConfig as Machine.AnyStateConfig
|
|
212
|
+
if (childConfig !== undefined) {
|
|
213
|
+
const node = Topology.getStateNodeDefinition(path, states[key]!)
|
|
214
|
+
if (node.states === undefined) {
|
|
215
|
+
throw new Error(`Machine expected state "${path}" to declare child states`)
|
|
216
|
+
}
|
|
217
|
+
if (typeof childConfig !== "object" || childConfig === null) {
|
|
218
|
+
throw new Error(`Machine expected state "${path}" child handlers to be an object`)
|
|
219
|
+
}
|
|
220
|
+
flattenHandlers(handlers, stateNodes, node.states, path, childConfig as Record<string, unknown>)
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const makeHandle = (self: Machine.Any): Machine.Any["handle"] =>
|
|
226
|
+
((config: Record<string, unknown>) => {
|
|
227
|
+
const handlers: Record<PropertyKey, Machine.AnyStateConfig> = Object.assign(
|
|
228
|
+
Object.create(null),
|
|
229
|
+
self.handlers
|
|
230
|
+
)
|
|
231
|
+
flattenHandlers(handlers, self.stateNodes, self.states, "", config)
|
|
232
|
+
return cloneWithHandlers(self, handlers)
|
|
233
|
+
}) as Machine.Any["handle"]
|
|
234
|
+
|
|
235
|
+
export const isMachine = (
|
|
236
|
+
u: unknown
|
|
237
|
+
): u is Machine.Any => hasProperty(u, TypeId) && u[TypeId] === TypeId
|
|
238
|
+
|
|
239
|
+
export const isFinal = <
|
|
240
|
+
const States extends Machine.StateSchemas,
|
|
241
|
+
const Events extends ReadonlyArray<Machine.TaggedSchema>,
|
|
242
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema>,
|
|
243
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
244
|
+
UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
|
|
245
|
+
E = never,
|
|
246
|
+
R = never,
|
|
247
|
+
InitialE = never,
|
|
248
|
+
InitialR = never,
|
|
249
|
+
FinalStates extends Machine.StateIdentifier<States> = never,
|
|
250
|
+
Output = never,
|
|
251
|
+
OutputStates extends Machine.StateIdentifier<States> = never,
|
|
252
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events
|
|
253
|
+
>(
|
|
254
|
+
machine: Machine<
|
|
255
|
+
States,
|
|
256
|
+
Events,
|
|
257
|
+
Input,
|
|
258
|
+
UnhandledStates,
|
|
259
|
+
E,
|
|
260
|
+
R,
|
|
261
|
+
InitialE,
|
|
262
|
+
InitialR,
|
|
263
|
+
FinalStates,
|
|
264
|
+
Output,
|
|
265
|
+
Emits,
|
|
266
|
+
OutputStates,
|
|
267
|
+
InputEvents
|
|
268
|
+
>,
|
|
269
|
+
state: Machine.Snapshot<States>
|
|
270
|
+
): state is Machine.SnapshotContainingFinal<States, FinalStates> => internalPlanner.isFinal(machine as any, state)
|
|
271
|
+
|
|
272
|
+
type SnapshotBuilderOptions = {
|
|
273
|
+
readonly mode: "initial" | "full"
|
|
274
|
+
readonly prefix: string
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
type FromMethodKind = "leaf" | "nested"
|
|
278
|
+
|
|
279
|
+
const withFrom = <Method extends (value: unknown, ...args: ReadonlyArray<any>) => unknown>(
|
|
280
|
+
method: Method,
|
|
281
|
+
kind: FromMethodKind
|
|
282
|
+
): Method & { readonly from: (...args: ReadonlyArray<any>) => unknown } => {
|
|
283
|
+
Object.defineProperty(method, "from", {
|
|
284
|
+
value: (...args: ReadonlyArray<any>) => {
|
|
285
|
+
const omitted = args.length === 0 || (kind === "nested" && args.length === 1 && typeof args[0] === "function")
|
|
286
|
+
const input = omitted ? {} : args[0]
|
|
287
|
+
const rest = omitted ? args : args.slice(1)
|
|
288
|
+
return method(Topology.makeStateInput(input), ...rest)
|
|
289
|
+
},
|
|
290
|
+
enumerable: false
|
|
291
|
+
})
|
|
292
|
+
return method as Method & { readonly from: (...args: ReadonlyArray<any>) => unknown }
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const makeSnapshotBuilder = (
|
|
296
|
+
states: Machine.StateTree,
|
|
297
|
+
options: SnapshotBuilderOptions
|
|
298
|
+
): unknown => {
|
|
299
|
+
const builder: Record<string, unknown> = {}
|
|
300
|
+
for (const key of Object.keys(states)) {
|
|
301
|
+
const definition = states[key]!
|
|
302
|
+
const pseudoType = (definition as { readonly type?: unknown }).type
|
|
303
|
+
if (pseudoType === "history") {
|
|
304
|
+
continue
|
|
305
|
+
}
|
|
306
|
+
const path = options.prefix === "" ? key : `${options.prefix}.${key}`
|
|
307
|
+
if (pseudoType === "choice") {
|
|
308
|
+
builder[key] = () => Topology.makeChoiceTarget(path, getParentPathRuntime(path))
|
|
309
|
+
continue
|
|
310
|
+
}
|
|
311
|
+
const node = Topology.getStateNodeDefinition(path, definition)
|
|
312
|
+
builder[key] = withFrom(
|
|
313
|
+
(value: unknown, selector?: (builder: unknown) => unknown) =>
|
|
314
|
+
makeSnapshotForNode(definition, key, value, selector, options),
|
|
315
|
+
node.states === undefined ? "leaf" : "nested"
|
|
316
|
+
)
|
|
317
|
+
}
|
|
318
|
+
return builder
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const makeParallelSnapshotBuilder = (
|
|
322
|
+
states: Machine.StateTree,
|
|
323
|
+
options: SnapshotBuilderOptions,
|
|
324
|
+
regions: Readonly<Record<string, unknown>>
|
|
325
|
+
): unknown => {
|
|
326
|
+
const builder: Record<string, unknown> = {}
|
|
327
|
+
Object.defineProperty(builder, SnapshotBuilderStateTypeId, {
|
|
328
|
+
value: regions,
|
|
329
|
+
enumerable: false
|
|
330
|
+
})
|
|
331
|
+
for (const key of Object.keys(states)) {
|
|
332
|
+
const definition = states[key]!
|
|
333
|
+
const pseudoType = (definition as { readonly type?: unknown }).type
|
|
334
|
+
if (pseudoType === "history" || pseudoType === "choice") {
|
|
335
|
+
continue
|
|
336
|
+
}
|
|
337
|
+
if (hasProperty(regions, key)) {
|
|
338
|
+
continue
|
|
339
|
+
}
|
|
340
|
+
const path = options.prefix === "" ? key : `${options.prefix}.${key}`
|
|
341
|
+
const node = Topology.getStateNodeDefinition(path, definition)
|
|
342
|
+
builder[key] = withFrom((value: unknown, selector?: (builder: unknown) => unknown) => {
|
|
343
|
+
const nextRegions: Record<string, unknown> = {}
|
|
344
|
+
for (const regionKey of Object.keys(regions)) {
|
|
345
|
+
nextRegions[regionKey] = regions[regionKey]
|
|
346
|
+
}
|
|
347
|
+
nextRegions[key] = makeSnapshotForNode(definition, key, value, selector, options)
|
|
348
|
+
return makeParallelSnapshotBuilder(states, options, nextRegions)
|
|
349
|
+
}, node.states === undefined ? "leaf" : "nested")
|
|
350
|
+
}
|
|
351
|
+
return builder
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const getParallelSnapshotBuilderRegions = (
|
|
355
|
+
path: string,
|
|
356
|
+
states: Machine.StateTree,
|
|
357
|
+
builder: unknown
|
|
358
|
+
): Readonly<Record<string, unknown>> => {
|
|
359
|
+
if (typeof builder !== "object" || builder === null || !hasProperty(builder, SnapshotBuilderStateTypeId)) {
|
|
360
|
+
throw new Error(`Machine expected parallel state "${path}" builder callback to return a builder`)
|
|
361
|
+
}
|
|
362
|
+
const regions = (builder as { readonly [SnapshotBuilderStateTypeId]: Readonly<Record<string, unknown>> })[
|
|
363
|
+
SnapshotBuilderStateTypeId
|
|
364
|
+
]
|
|
365
|
+
for (const key of Object.keys(states)) {
|
|
366
|
+
const pseudoType = (states[key] as { readonly type?: unknown }).type
|
|
367
|
+
if (pseudoType === "history" || pseudoType === "choice") {
|
|
368
|
+
continue
|
|
369
|
+
}
|
|
370
|
+
if (!hasProperty(regions, key)) {
|
|
371
|
+
throw new Error(`Machine expected parallel state "${path}" builder callback to provide region "${key}"`)
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return regions
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const makeSnapshotForNode = (
|
|
378
|
+
definition: Machine.TaggedSchema | Machine.StateNodeConfig,
|
|
379
|
+
key: string,
|
|
380
|
+
value: unknown,
|
|
381
|
+
selector: ((builder: unknown) => unknown) | undefined,
|
|
382
|
+
options: SnapshotBuilderOptions
|
|
383
|
+
): Record<string, unknown> => {
|
|
384
|
+
const path = options.prefix === "" ? key : `${options.prefix}.${key}`
|
|
385
|
+
const node = Topology.getStateNodeDefinition(path, definition)
|
|
386
|
+
const snapshot: Record<string, unknown> = {
|
|
387
|
+
path,
|
|
388
|
+
value
|
|
389
|
+
}
|
|
390
|
+
if (node.states === undefined) {
|
|
391
|
+
return snapshot
|
|
392
|
+
}
|
|
393
|
+
if (selector === undefined) {
|
|
394
|
+
throw new Error(`Machine expected state "${path}" builder to provide active child states`)
|
|
395
|
+
}
|
|
396
|
+
if (node.type === "parallel") {
|
|
397
|
+
const builder = makeParallelSnapshotBuilder(node.states, { ...options, prefix: path }, {})
|
|
398
|
+
const selected = selector(builder)
|
|
399
|
+
snapshot.states = getParallelSnapshotBuilderRegions(path, node.states, selected)
|
|
400
|
+
return snapshot
|
|
401
|
+
}
|
|
402
|
+
const childStates = options.mode === "initial" && node.initial !== undefined
|
|
403
|
+
? { [node.initial]: node.states[node.initial]! }
|
|
404
|
+
: node.states
|
|
405
|
+
const selected = selector(makeSnapshotBuilder(childStates, { ...options, prefix: path }))
|
|
406
|
+
snapshot.state = selected
|
|
407
|
+
return snapshot
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const getTargetBuilderNode = (
|
|
411
|
+
stateNodes: Machine.StateNodes,
|
|
412
|
+
path: string
|
|
413
|
+
): Machine.StateNode => {
|
|
414
|
+
const node = stateNodes.byPath.get(path)
|
|
415
|
+
if (node === undefined) {
|
|
416
|
+
throw new Error(`Machine expected state path "${path}" to exist`)
|
|
417
|
+
}
|
|
418
|
+
return node
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const getLocalTargetScope = (
|
|
422
|
+
stateNodes: Machine.StateNodes,
|
|
423
|
+
source: string
|
|
424
|
+
): string | undefined => {
|
|
425
|
+
let current: string | undefined = source
|
|
426
|
+
while (current !== undefined) {
|
|
427
|
+
const node = stateNodes.byPath.get(current)
|
|
428
|
+
if (node === undefined) {
|
|
429
|
+
return undefined
|
|
430
|
+
}
|
|
431
|
+
if (node.type === "compound") {
|
|
432
|
+
return node.path
|
|
433
|
+
}
|
|
434
|
+
current = node.parent
|
|
435
|
+
}
|
|
436
|
+
return undefined
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
const hasTargetValues = (
|
|
440
|
+
values: Readonly<Record<string, unknown>> | undefined
|
|
441
|
+
): values is Readonly<Record<string, unknown>> => values !== undefined && Object.keys(values).length > 0
|
|
442
|
+
|
|
443
|
+
const makeTargetWithValues = (
|
|
444
|
+
path: string,
|
|
445
|
+
value: unknown,
|
|
446
|
+
values: Readonly<Record<string, unknown>> | undefined
|
|
447
|
+
): Machine.Target<any, any> =>
|
|
448
|
+
hasTargetValues(values)
|
|
449
|
+
? Topology.makeTarget(path as any, value as any, { values: values as any })
|
|
450
|
+
: Topology.makeTarget(path as any, value as any)
|
|
451
|
+
|
|
452
|
+
const getTargetBuilderDefinition = (
|
|
453
|
+
states: Machine.StateTree,
|
|
454
|
+
targetPath: string
|
|
455
|
+
): Machine.TaggedSchema | Machine.StateNodeConfig => {
|
|
456
|
+
let children = states
|
|
457
|
+
let path = ""
|
|
458
|
+
let definition: Machine.TaggedSchema | Machine.StateNodeConfig | undefined
|
|
459
|
+
for (const key of targetPath.split(".")) {
|
|
460
|
+
if (!hasProperty(children, key)) {
|
|
461
|
+
throw new Error(`Machine expected state path "${targetPath}" to exist`)
|
|
462
|
+
}
|
|
463
|
+
definition = children[key]!
|
|
464
|
+
path = path === "" ? key : `${path}.${key}`
|
|
465
|
+
const node = Topology.getStateNodeDefinition(path, definition)
|
|
466
|
+
children = node.states ?? {}
|
|
467
|
+
}
|
|
468
|
+
return definition!
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
const makeParallelTarget = (
|
|
472
|
+
states: Machine.StateTree,
|
|
473
|
+
node: Machine.StateNode,
|
|
474
|
+
value: unknown,
|
|
475
|
+
selector: ((builder: unknown) => unknown) | undefined,
|
|
476
|
+
values: Readonly<Record<string, unknown>> | undefined
|
|
477
|
+
): Machine.Target<any, any> => {
|
|
478
|
+
if (selector === undefined) {
|
|
479
|
+
throw new Error(`Machine expected parallel target "${node.path}" builder to provide every active region`)
|
|
480
|
+
}
|
|
481
|
+
const snapshot = makeSnapshotForNode(
|
|
482
|
+
getTargetBuilderDefinition(states, node.path),
|
|
483
|
+
node.key,
|
|
484
|
+
value,
|
|
485
|
+
selector,
|
|
486
|
+
{ mode: "full", prefix: node.parent ?? "" }
|
|
487
|
+
)
|
|
488
|
+
return Topology.makeTarget(node.path as any, value as any, {
|
|
489
|
+
snapshot: snapshot as any,
|
|
490
|
+
values: values as any
|
|
491
|
+
})
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const extendTargetValues = (
|
|
495
|
+
values: Readonly<Record<string, unknown>> | undefined,
|
|
496
|
+
path: string,
|
|
497
|
+
value: unknown
|
|
498
|
+
): Readonly<Record<string, unknown>> => {
|
|
499
|
+
const next: Record<string, unknown> = {}
|
|
500
|
+
if (values !== undefined) {
|
|
501
|
+
for (const key of Object.keys(values)) {
|
|
502
|
+
next[key] = values[key]
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
next[path] = value
|
|
506
|
+
return next
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
const makeLocalTargetChildBuilder = (
|
|
510
|
+
states: Machine.StateTree,
|
|
511
|
+
stateNodes: Machine.StateNodes,
|
|
512
|
+
parentPath: string,
|
|
513
|
+
values: Readonly<Record<string, unknown>> | undefined,
|
|
514
|
+
source: string
|
|
515
|
+
): unknown => {
|
|
516
|
+
const parent = getTargetBuilderNode(stateNodes, parentPath)
|
|
517
|
+
const builder: Record<string, unknown> = {}
|
|
518
|
+
for (
|
|
519
|
+
const childPath of Array.from(stateNodes.byPath.values())
|
|
520
|
+
.filter((node) => node.parent === parent.path && node.type !== "history")
|
|
521
|
+
.map((node) => node.path)
|
|
522
|
+
) {
|
|
523
|
+
const child = getTargetBuilderNode(stateNodes, childPath)
|
|
524
|
+
if (child.type === "choice") {
|
|
525
|
+
builder[child.key] = () => Topology.makeChoiceTarget(child.path, parent.path, values)
|
|
526
|
+
continue
|
|
527
|
+
}
|
|
528
|
+
builder[child.key] = withFrom((value: unknown, selector?: (builder: unknown) => unknown) => {
|
|
529
|
+
if (child.type === "atomic" || child.type === "final") {
|
|
530
|
+
return makeTargetWithValues(child.path, value, values)
|
|
531
|
+
}
|
|
532
|
+
if (child.type === "parallel") {
|
|
533
|
+
if (source !== child.path && !source.startsWith(`${child.path}.`)) {
|
|
534
|
+
return makeParallelTarget(states, child, value, selector, values)
|
|
535
|
+
}
|
|
536
|
+
if (selector === undefined) {
|
|
537
|
+
throw new Error(`Machine expected target "${child.path}" builder to provide an active child state`)
|
|
538
|
+
}
|
|
539
|
+
return selector(makeLocalTargetChildBuilder(
|
|
540
|
+
states,
|
|
541
|
+
stateNodes,
|
|
542
|
+
child.path,
|
|
543
|
+
extendTargetValues(values, child.path, value),
|
|
544
|
+
source
|
|
545
|
+
))
|
|
546
|
+
}
|
|
547
|
+
if (selector === undefined) {
|
|
548
|
+
throw new Error(`Machine expected target "${child.path}" builder to provide an active child state`)
|
|
549
|
+
}
|
|
550
|
+
return selector(makeLocalTargetChildBuilder(
|
|
551
|
+
states,
|
|
552
|
+
stateNodes,
|
|
553
|
+
child.path,
|
|
554
|
+
extendTargetValues(values, child.path, value),
|
|
555
|
+
source
|
|
556
|
+
))
|
|
557
|
+
}, child.type === "atomic" || child.type === "final" ? "leaf" : "nested")
|
|
558
|
+
}
|
|
559
|
+
return builder
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
const makeLocalTargetBuilder = (
|
|
563
|
+
states: Machine.StateTree,
|
|
564
|
+
stateNodes: Machine.StateNodes,
|
|
565
|
+
source: string
|
|
566
|
+
): unknown => {
|
|
567
|
+
const scope = getLocalTargetScope(stateNodes, source)
|
|
568
|
+
if (scope === undefined) {
|
|
569
|
+
return {}
|
|
570
|
+
}
|
|
571
|
+
const builder = makeLocalTargetChildBuilder(states, stateNodes, scope, undefined, source) as Record<string, unknown>
|
|
572
|
+
builder.with = withFrom((value: unknown, selector?: (builder: unknown) => unknown) => {
|
|
573
|
+
if (selector === undefined) {
|
|
574
|
+
throw new Error(`Machine expected target "${scope}" builder to provide an active child state`)
|
|
575
|
+
}
|
|
576
|
+
return selector(makeLocalTargetChildBuilder(states, stateNodes, scope, { [scope]: value }, source))
|
|
577
|
+
}, "nested")
|
|
578
|
+
return builder
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
const addBranchTargetChildren = (
|
|
582
|
+
builder: Record<string, unknown>,
|
|
583
|
+
states: Machine.StateTree,
|
|
584
|
+
stateNodes: Machine.StateNodes,
|
|
585
|
+
parentPath: string,
|
|
586
|
+
values: Readonly<Record<string, unknown>> | undefined,
|
|
587
|
+
source: string
|
|
588
|
+
): void => {
|
|
589
|
+
const parent = getTargetBuilderNode(stateNodes, parentPath)
|
|
590
|
+
for (
|
|
591
|
+
const childPath of Array.from(stateNodes.byPath.values())
|
|
592
|
+
.filter((node) => node.parent === parent.path && node.type !== "history")
|
|
593
|
+
.map((node) => node.path)
|
|
594
|
+
) {
|
|
595
|
+
const child = getTargetBuilderNode(stateNodes, childPath)
|
|
596
|
+
if (child.type === "choice") {
|
|
597
|
+
builder[child.key] = () => Topology.makeChoiceTarget(child.path, parent.path, values)
|
|
598
|
+
continue
|
|
599
|
+
}
|
|
600
|
+
builder[child.key] = makeBranchTargetNodeBuilder(states, stateNodes, child.path, values, source)
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
const makeBranchTargetNodeBuilder = (
|
|
605
|
+
states: Machine.StateTree,
|
|
606
|
+
stateNodes: Machine.StateNodes,
|
|
607
|
+
path: string,
|
|
608
|
+
values: Readonly<Record<string, unknown>> | undefined,
|
|
609
|
+
source: string
|
|
610
|
+
): unknown => {
|
|
611
|
+
const node = getTargetBuilderNode(stateNodes, path)
|
|
612
|
+
if (node.type === "atomic" || node.type === "final") {
|
|
613
|
+
return withFrom((value: unknown) => makeTargetWithValues(node.path, value, values), "leaf")
|
|
614
|
+
}
|
|
615
|
+
const builder = withFrom((value: unknown, selector?: (builder: unknown) => unknown) => {
|
|
616
|
+
if (node.type === "parallel") {
|
|
617
|
+
if (source !== node.path && !source.startsWith(`${node.path}.`)) {
|
|
618
|
+
return makeParallelTarget(states, node, value, selector, values)
|
|
619
|
+
}
|
|
620
|
+
if (selector === undefined) {
|
|
621
|
+
throw new Error(`Machine expected target "${node.path}" builder to provide an active child state`)
|
|
622
|
+
}
|
|
623
|
+
const nextBuilder: Record<string, unknown> = {}
|
|
624
|
+
addBranchTargetChildren(
|
|
625
|
+
nextBuilder,
|
|
626
|
+
states,
|
|
627
|
+
stateNodes,
|
|
628
|
+
node.path,
|
|
629
|
+
extendTargetValues(values, node.path, value),
|
|
630
|
+
source
|
|
631
|
+
)
|
|
632
|
+
return selector(nextBuilder)
|
|
633
|
+
}
|
|
634
|
+
if (selector === undefined) {
|
|
635
|
+
throw new Error(`Machine expected target "${node.path}" builder to provide an active child state`)
|
|
636
|
+
}
|
|
637
|
+
const nextBuilder: Record<string, unknown> = {}
|
|
638
|
+
addBranchTargetChildren(
|
|
639
|
+
nextBuilder,
|
|
640
|
+
states,
|
|
641
|
+
stateNodes,
|
|
642
|
+
node.path,
|
|
643
|
+
extendTargetValues(values, node.path, value),
|
|
644
|
+
source
|
|
645
|
+
)
|
|
646
|
+
return selector(nextBuilder)
|
|
647
|
+
}, "nested") as unknown as Record<string, unknown>
|
|
648
|
+
if (node.type !== "parallel" || source === node.path || source.startsWith(`${node.path}.`)) {
|
|
649
|
+
addBranchTargetChildren(builder, states, stateNodes, node.path, values, source)
|
|
650
|
+
}
|
|
651
|
+
return builder
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
const makeBranchTargetBuilder = (
|
|
655
|
+
states: Machine.StateTree,
|
|
656
|
+
stateNodes: Machine.StateNodes,
|
|
657
|
+
source: string
|
|
658
|
+
): unknown => {
|
|
659
|
+
const rootPath = source.split(".")[0]!
|
|
660
|
+
const root = getTargetBuilderNode(stateNodes, rootPath)
|
|
661
|
+
return {
|
|
662
|
+
[root.key]: makeBranchTargetNodeBuilder(states, stateNodes, root.path, undefined, source)
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
const makeHistoryTargetBuilder = (
|
|
667
|
+
states: Machine.StateTree,
|
|
668
|
+
prefix: string
|
|
669
|
+
): unknown => {
|
|
670
|
+
const builder: Record<string, unknown> = {}
|
|
671
|
+
for (const key of Object.keys(states)) {
|
|
672
|
+
const path = prefix === "" ? key : `${prefix}.${key}`
|
|
673
|
+
const definition = Topology.getStateNodeDefinition(path, states[key]!)
|
|
674
|
+
if (definition.type === "history") {
|
|
675
|
+
const parent = getParentPathRuntime(path)
|
|
676
|
+
builder[key] = () => Topology.makeHistoryTarget(path, parent)
|
|
677
|
+
continue
|
|
678
|
+
}
|
|
679
|
+
if (definition.states !== undefined) {
|
|
680
|
+
builder[key] = makeHistoryTargetBuilder(definition.states, path)
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
return builder
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
const getParentPathRuntime = (path: string): string => {
|
|
687
|
+
const separator = path.lastIndexOf(".")
|
|
688
|
+
if (separator < 0) {
|
|
689
|
+
throw new Error(`Machine expected history state "${path}" to have an active parent`)
|
|
690
|
+
}
|
|
691
|
+
return path.slice(0, separator)
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
const makeTargetBuilder = <const States extends Machine.StateSchemas>(
|
|
695
|
+
states: States,
|
|
696
|
+
stateNodes: Machine.StateNodes
|
|
697
|
+
) => {
|
|
698
|
+
const full = makeSnapshotBuilder(states, { mode: "full", prefix: "" }) as Machine.FullTargetBuilder<States>
|
|
699
|
+
const history = makeHistoryTargetBuilder(states, "") as Machine.HistoryTargetBuilder<States>
|
|
700
|
+
return <Source extends Machine.StateNodeIdentifier<States>>(source: Source): Machine.TargetBuilder<States, Source> =>
|
|
701
|
+
({
|
|
702
|
+
local: makeLocalTargetBuilder(states, stateNodes, source),
|
|
703
|
+
branch: makeBranchTargetBuilder(states, stateNodes, source),
|
|
704
|
+
full,
|
|
705
|
+
history
|
|
706
|
+
}) as Machine.TargetBuilder<States, Source>
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
export const defineStates: DefineStates = (<const States extends Machine.StateSchemas>(
|
|
710
|
+
states: States
|
|
711
|
+
): Machine.DefinedStates<States> => {
|
|
712
|
+
StateDefinition.validateStateDefinitions(states, "Machine.defineStates")
|
|
713
|
+
return {
|
|
714
|
+
states,
|
|
715
|
+
initial: makeSnapshotBuilder(states, { mode: "initial", prefix: "" }) as Machine.InitialBuilder<States>,
|
|
716
|
+
get:
|
|
717
|
+
((snapshot: Machine.AtomicSnapshot<string, unknown>, path: string) =>
|
|
718
|
+
Topology.getSnapshotByPath(snapshot, path).pipe(
|
|
719
|
+
Option.map((snapshot) => snapshot.value)
|
|
720
|
+
)) as Machine.DefinedStates<States>["get"],
|
|
721
|
+
getWithParents: ((snapshot, path) => {
|
|
722
|
+
const parents: Record<string, unknown> = {}
|
|
723
|
+
return Topology.getSnapshotByPath(snapshot, path, parents).pipe(
|
|
724
|
+
Option.map((snapshot) => ({ value: snapshot.value, parents }))
|
|
725
|
+
)
|
|
726
|
+
}) as Machine.DefinedStates<States>["getWithParents"],
|
|
727
|
+
getSnapshot: Topology.getSnapshotByPath as unknown as Machine.DefinedStates<States>["getSnapshot"],
|
|
728
|
+
matches:
|
|
729
|
+
((snapshot: Machine.AtomicSnapshot<string, unknown>, path: string) =>
|
|
730
|
+
Option.isSome(Topology.getSnapshotByPath(snapshot, path))) as Machine.DefinedStates<States>["matches"]
|
|
731
|
+
}
|
|
732
|
+
}) as DefineStates
|
|
733
|
+
|
|
734
|
+
type MakeConfig<
|
|
735
|
+
States extends Machine.StateSchemas,
|
|
736
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
|
|
737
|
+
Emits extends ReadonlyArray<Machine.TaggedSchema>,
|
|
738
|
+
Input extends Schema.Top,
|
|
739
|
+
InitialE,
|
|
740
|
+
InitialR,
|
|
741
|
+
InternalEvents extends ReadonlyArray<Machine.TaggedSchema>
|
|
742
|
+
> = {
|
|
743
|
+
readonly id?: string
|
|
744
|
+
readonly states: States & DefineStateTreeInput<NoInfer<States>>
|
|
745
|
+
readonly events: InputEvents & ValidateInputEventProtocol<NoInfer<InputEvents>>
|
|
746
|
+
readonly internalEvents?:
|
|
747
|
+
& InternalEvents
|
|
748
|
+
& ValidateInternalEventProtocol<
|
|
749
|
+
NoInfer<InputEvents>,
|
|
750
|
+
NoInfer<InternalEvents>
|
|
751
|
+
>
|
|
752
|
+
readonly emits?: Emits
|
|
753
|
+
readonly input?: Input
|
|
754
|
+
readonly initial: (...args: [...Machine.InputArgs<Input>]) => Machine.InitialResult<States, InitialE, InitialR>
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
type MakeResult<
|
|
758
|
+
States extends Machine.StateSchemas,
|
|
759
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
|
|
760
|
+
Emits extends ReadonlyArray<Machine.TaggedSchema>,
|
|
761
|
+
Input extends Schema.Top,
|
|
762
|
+
InitialE,
|
|
763
|
+
InitialR,
|
|
764
|
+
InternalEvents extends ReadonlyArray<Machine.TaggedSchema>
|
|
765
|
+
> = Machine<
|
|
766
|
+
States,
|
|
767
|
+
readonly [...InputEvents, ...InternalEvents],
|
|
768
|
+
Input,
|
|
769
|
+
Machine.StateIdentifier<States>,
|
|
770
|
+
never,
|
|
771
|
+
never,
|
|
772
|
+
InitialE,
|
|
773
|
+
InitialR,
|
|
774
|
+
Machine.FinalStateFromDefinition<States>,
|
|
775
|
+
Machine.TerminalOutput<States>,
|
|
776
|
+
Emits,
|
|
777
|
+
never,
|
|
778
|
+
InputEvents
|
|
779
|
+
>
|
|
780
|
+
|
|
781
|
+
interface Make {
|
|
782
|
+
<
|
|
783
|
+
const States extends Machine.StateSchemas,
|
|
784
|
+
const InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
|
|
785
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
|
|
786
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
787
|
+
InitialE = never,
|
|
788
|
+
InitialR = never,
|
|
789
|
+
const InternalEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
|
|
790
|
+
>(
|
|
791
|
+
config: MakeConfig<States, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents>,
|
|
792
|
+
..._validation: ValidateDefinedStates<NoInfer<States>>
|
|
793
|
+
): MakeResult<States, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents>
|
|
794
|
+
<
|
|
795
|
+
const States extends Machine.StateSchemas,
|
|
796
|
+
const InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
|
|
797
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
|
|
798
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
799
|
+
InitialE = never,
|
|
800
|
+
InitialR = never,
|
|
801
|
+
const InternalEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
|
|
802
|
+
>(
|
|
803
|
+
config:
|
|
804
|
+
& Omit<MakeConfig<States, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents>, "states">
|
|
805
|
+
& { readonly states: InvalidDefinedStateTreeInput<States> }
|
|
806
|
+
): never
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
export const make: Make = (<
|
|
810
|
+
const States extends Machine.StateSchemas,
|
|
811
|
+
const InputEvents extends ReadonlyArray<Machine.TaggedSchema>,
|
|
812
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
|
|
813
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
814
|
+
InitialE = never,
|
|
815
|
+
InitialR = never,
|
|
816
|
+
const InternalEvents extends ReadonlyArray<Machine.TaggedSchema> = readonly []
|
|
817
|
+
>(
|
|
818
|
+
config: {
|
|
819
|
+
readonly id?: string
|
|
820
|
+
readonly states: States
|
|
821
|
+
readonly events: InputEvents
|
|
822
|
+
readonly internalEvents?: InternalEvents
|
|
823
|
+
readonly emits?: Emits
|
|
824
|
+
readonly input?: Input
|
|
825
|
+
readonly initial: (...args: [...Machine.InputArgs<Input>]) => Machine.InitialResult<States, InitialE, InitialR>
|
|
826
|
+
}
|
|
827
|
+
): MakeResult<States, InputEvents, Emits, Input, InitialE, InitialR, InternalEvents> => {
|
|
828
|
+
StateDefinition.validateStateDefinitions(config.states, "Machine.make")
|
|
829
|
+
const self = Object.create(Proto)
|
|
830
|
+
self.states = config.states
|
|
831
|
+
self.events = config.events
|
|
832
|
+
self.internalEvents = config.internalEvents ?? []
|
|
833
|
+
self.emits = config.emits ?? []
|
|
834
|
+
self.input = config.input
|
|
835
|
+
self.id = config.id
|
|
836
|
+
self.initial = config.initial
|
|
837
|
+
self.stateNodes = Topology.compileStateNodes(config.states)
|
|
838
|
+
self.makeTargetBuilder = makeTargetBuilder(config.states, self.stateNodes)
|
|
839
|
+
self.handlers = Object.create(null)
|
|
840
|
+
self.handle = makeHandle(self)
|
|
841
|
+
Protocol.setProtocol(self)
|
|
842
|
+
return self
|
|
843
|
+
}) as Make
|
|
844
|
+
|
|
845
|
+
type EventConstructorArgs<EventSchema extends Machine.TaggedSchema> = {} extends EventSchema["~type.make.in"] ?
|
|
846
|
+
[input?: EventSchema["~type.make.in"]]
|
|
847
|
+
: [input: EventSchema["~type.make.in"]]
|
|
848
|
+
|
|
849
|
+
export const event = <
|
|
850
|
+
const M extends Machine.Any,
|
|
851
|
+
const EventSchema extends Machine.TaggedSchema
|
|
852
|
+
>(
|
|
853
|
+
machine: M,
|
|
854
|
+
schema: EventSchema & ([EventSchema["Type"]] extends [Machine.Event<M>] ? unknown : never),
|
|
855
|
+
...args: EventConstructorArgs<EventSchema>
|
|
856
|
+
): EventSchema["Type"] => Protocol.makeEvent(machine, schema, args.length === 0 ? {} : args[0])
|
|
857
|
+
|
|
858
|
+
export const encodeSnapshot: <
|
|
859
|
+
const States extends Machine.StateSchemas,
|
|
860
|
+
const Events extends ReadonlyArray<Machine.TaggedSchema>,
|
|
861
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
|
|
862
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
863
|
+
UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
|
|
864
|
+
E = never,
|
|
865
|
+
R = never,
|
|
866
|
+
InitialE = never,
|
|
867
|
+
InitialR = never,
|
|
868
|
+
FinalStates extends Machine.StateIdentifier<States> = never,
|
|
869
|
+
Output = never,
|
|
870
|
+
OutputStates extends Machine.StateIdentifier<States> = never,
|
|
871
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events
|
|
872
|
+
>(
|
|
873
|
+
machine: Machine<
|
|
874
|
+
States,
|
|
875
|
+
Events,
|
|
876
|
+
Input,
|
|
877
|
+
UnhandledStates,
|
|
878
|
+
E,
|
|
879
|
+
R,
|
|
880
|
+
InitialE,
|
|
881
|
+
InitialR,
|
|
882
|
+
FinalStates,
|
|
883
|
+
Output,
|
|
884
|
+
Emits,
|
|
885
|
+
OutputStates,
|
|
886
|
+
InputEvents
|
|
887
|
+
>,
|
|
888
|
+
snapshot: Machine.Snapshot<States>
|
|
889
|
+
) => Effect.Effect<
|
|
890
|
+
Machine.EncodedSnapshot,
|
|
891
|
+
MachineSchemaEncodeError,
|
|
892
|
+
Machine.SnapshotEncodingServices<States>
|
|
893
|
+
> = Serialization.encodeSnapshot as any
|
|
894
|
+
|
|
895
|
+
export const decodeSnapshot: <
|
|
896
|
+
const States extends Machine.StateSchemas,
|
|
897
|
+
const Events extends ReadonlyArray<Machine.TaggedSchema>,
|
|
898
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
|
|
899
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
900
|
+
UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
|
|
901
|
+
E = never,
|
|
902
|
+
R = never,
|
|
903
|
+
InitialE = never,
|
|
904
|
+
InitialR = never,
|
|
905
|
+
FinalStates extends Machine.StateIdentifier<States> = never,
|
|
906
|
+
Output = never,
|
|
907
|
+
OutputStates extends Machine.StateIdentifier<States> = never,
|
|
908
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events
|
|
909
|
+
>(
|
|
910
|
+
machine: Machine<
|
|
911
|
+
States,
|
|
912
|
+
Events,
|
|
913
|
+
Input,
|
|
914
|
+
UnhandledStates,
|
|
915
|
+
E,
|
|
916
|
+
R,
|
|
917
|
+
InitialE,
|
|
918
|
+
InitialR,
|
|
919
|
+
FinalStates,
|
|
920
|
+
Output,
|
|
921
|
+
Emits,
|
|
922
|
+
OutputStates,
|
|
923
|
+
InputEvents
|
|
924
|
+
>,
|
|
925
|
+
encoded: unknown
|
|
926
|
+
) => Effect.Effect<
|
|
927
|
+
Machine.Snapshot<States>,
|
|
928
|
+
MachineSchemaDecodeError,
|
|
929
|
+
Machine.SnapshotDecodingServices<States>
|
|
930
|
+
> = Serialization.decodeSnapshot as any
|
|
931
|
+
|
|
932
|
+
export const invoke = <
|
|
933
|
+
ChildState,
|
|
934
|
+
ChildEvent,
|
|
935
|
+
ChildError = never,
|
|
936
|
+
ChildRequirements = never,
|
|
937
|
+
ChildOutput = never,
|
|
938
|
+
ChildInitialError = never,
|
|
939
|
+
Event = never,
|
|
940
|
+
Address extends ChildAddress<never> | undefined = undefined
|
|
941
|
+
>(
|
|
942
|
+
config:
|
|
943
|
+
& {
|
|
944
|
+
readonly id: InvokeLifecycleId
|
|
945
|
+
readonly src: () => Logic<
|
|
946
|
+
ChildState,
|
|
947
|
+
ChildEvent,
|
|
948
|
+
ChildError,
|
|
949
|
+
ChildRequirements,
|
|
950
|
+
ChildOutput,
|
|
951
|
+
ChildInitialError
|
|
952
|
+
>
|
|
953
|
+
readonly snapshot?: (
|
|
954
|
+
context: Machine.InvokeSnapshotContext<ChildState, ChildError, ChildOutput>
|
|
955
|
+
) => Event | undefined
|
|
956
|
+
}
|
|
957
|
+
& ([Address] extends [undefined] ? {
|
|
958
|
+
readonly address?: never
|
|
959
|
+
}
|
|
960
|
+
: {
|
|
961
|
+
readonly address: Exclude<Address, undefined>
|
|
962
|
+
} & ChildAddress.Compatibility<Exclude<Address, undefined>, NoInfer<ChildEvent>>)
|
|
963
|
+
): Machine.InvokeConfig<
|
|
964
|
+
any,
|
|
965
|
+
any,
|
|
966
|
+
any,
|
|
967
|
+
any,
|
|
968
|
+
Event,
|
|
969
|
+
ChildState,
|
|
970
|
+
ChildEvent,
|
|
971
|
+
ChildError,
|
|
972
|
+
ChildRequirements,
|
|
973
|
+
ChildOutput,
|
|
974
|
+
ChildInitialError
|
|
975
|
+
> => ({
|
|
976
|
+
...config,
|
|
977
|
+
[InvokeTypeId]: undefined as any,
|
|
978
|
+
[Activities.ActivityMetadataTypeId]: { type: "process" }
|
|
979
|
+
})
|
|
980
|
+
|
|
981
|
+
type InvokeEffectResult<Requirements, Event> = Machine.InvokeConfig<
|
|
982
|
+
any,
|
|
983
|
+
any,
|
|
984
|
+
any,
|
|
985
|
+
any,
|
|
986
|
+
never,
|
|
987
|
+
void,
|
|
988
|
+
never,
|
|
989
|
+
never,
|
|
990
|
+
Requirements,
|
|
991
|
+
Event | void,
|
|
992
|
+
never
|
|
993
|
+
>
|
|
994
|
+
|
|
995
|
+
type InvokeEffectIsInfallible<Fx extends Effect.Effect<any, any, any>> = IsAny<Effect.Error<Fx>> extends true ? false
|
|
996
|
+
: [Effect.Error<Fx>] extends [never] ? true
|
|
997
|
+
: false
|
|
998
|
+
|
|
999
|
+
type InvokeEffectConfig<
|
|
1000
|
+
Fx extends Effect.Effect<any, any, any>,
|
|
1001
|
+
SuccessEvent,
|
|
1002
|
+
FailureEvent
|
|
1003
|
+
> =
|
|
1004
|
+
& {
|
|
1005
|
+
readonly id: InvokeLifecycleId
|
|
1006
|
+
readonly effect: Fx
|
|
1007
|
+
readonly onSuccess: (value: NoInfer<Effect.Success<Fx>>) => SuccessEvent | void
|
|
1008
|
+
}
|
|
1009
|
+
& (
|
|
1010
|
+
InvokeEffectIsInfallible<Fx> extends true ? {
|
|
1011
|
+
readonly onFailure?: never
|
|
1012
|
+
}
|
|
1013
|
+
: {
|
|
1014
|
+
readonly onFailure: (error: NoInfer<Effect.Error<Fx>>) => FailureEvent | void
|
|
1015
|
+
}
|
|
1016
|
+
)
|
|
1017
|
+
|
|
1018
|
+
export const invokeEffect = <
|
|
1019
|
+
const Fx extends Effect.Effect<any, any, any>,
|
|
1020
|
+
SuccessEvent,
|
|
1021
|
+
FailureEvent = never
|
|
1022
|
+
>(
|
|
1023
|
+
config: InvokeEffectConfig<Fx, SuccessEvent, FailureEvent>
|
|
1024
|
+
): InvokeEffectResult<
|
|
1025
|
+
Effect.Services<Fx>,
|
|
1026
|
+
SuccessEvent | (InvokeEffectIsInfallible<Fx> extends true ? never : FailureEvent)
|
|
1027
|
+
> =>
|
|
1028
|
+
((config: {
|
|
1029
|
+
readonly id: string
|
|
1030
|
+
readonly effect: Effect.Effect<unknown, unknown, unknown>
|
|
1031
|
+
readonly onSuccess: (value: unknown) => unknown
|
|
1032
|
+
readonly onFailure?: (error: unknown) => unknown
|
|
1033
|
+
}) => ({
|
|
1034
|
+
...invoke({
|
|
1035
|
+
id: config.id,
|
|
1036
|
+
src: () =>
|
|
1037
|
+
effect(
|
|
1038
|
+
config.onFailure === undefined
|
|
1039
|
+
? Effect.map(config.effect, config.onSuccess)
|
|
1040
|
+
: Effect.matchEffect(config.effect, {
|
|
1041
|
+
onFailure: (error) => Effect.succeed(config.onFailure!(error)),
|
|
1042
|
+
onSuccess: (value) => Effect.succeed(config.onSuccess(value))
|
|
1043
|
+
})
|
|
1044
|
+
)
|
|
1045
|
+
}),
|
|
1046
|
+
[Activities.ActivityMetadataTypeId]: {
|
|
1047
|
+
type: "effect",
|
|
1048
|
+
outcomes: {
|
|
1049
|
+
success: "dynamic",
|
|
1050
|
+
failure: config.onFailure === undefined ? "none" : "dynamic"
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
}))(config as any) as any
|
|
1054
|
+
|
|
1055
|
+
export const after = <Event extends { readonly _tag: PropertyKey }>(
|
|
1056
|
+
duration: Duration.Input,
|
|
1057
|
+
event: Event,
|
|
1058
|
+
options?: { readonly id?: InvokeLifecycleId }
|
|
1059
|
+
): InvokeEffectResult<never, Event> => ({
|
|
1060
|
+
...invoke({
|
|
1061
|
+
id: options?.id ?? `Machine.after:${String(event._tag)}`,
|
|
1062
|
+
src: () => effect(Effect.as(Effect.sleep(duration), event))
|
|
1063
|
+
}),
|
|
1064
|
+
[Activities.ActivityMetadataTypeId]: {
|
|
1065
|
+
type: "timer",
|
|
1066
|
+
duration: Duration.format(Duration.fromInputUnsafe(duration)),
|
|
1067
|
+
event: String(event._tag)
|
|
1068
|
+
}
|
|
1069
|
+
})
|
|
1070
|
+
|
|
1071
|
+
export const retag = (
|
|
1072
|
+
target: Machine.TaggedSchema,
|
|
1073
|
+
source: { readonly _tag: PropertyKey },
|
|
1074
|
+
patch?: unknown
|
|
1075
|
+
): any => {
|
|
1076
|
+
const { _tag: _, ...fields } = source
|
|
1077
|
+
return target.make({ ...fields, ...((patch ?? {}) as object) } as never)
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
type InvokeMachineInput<Input extends Schema.Top> = Input extends typeof Schema.Void ? {
|
|
1081
|
+
readonly input?: never
|
|
1082
|
+
}
|
|
1083
|
+
: {
|
|
1084
|
+
readonly input: Input["Type"]
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
export const invokeMachine: {
|
|
1088
|
+
<
|
|
1089
|
+
const States extends Machine.StateSchemas,
|
|
1090
|
+
const Events extends ReadonlyArray<Machine.TaggedSchema>,
|
|
1091
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
|
|
1092
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
1093
|
+
UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
|
|
1094
|
+
E = never,
|
|
1095
|
+
R = never,
|
|
1096
|
+
InitialE = never,
|
|
1097
|
+
InitialR = never,
|
|
1098
|
+
FinalStates extends Machine.StateIdentifier<States> = never,
|
|
1099
|
+
Output = never,
|
|
1100
|
+
SnapshotEvent = never,
|
|
1101
|
+
DoneEvent = never,
|
|
1102
|
+
Id extends string = string,
|
|
1103
|
+
OutputStates extends Machine.StateIdentifier<States> = never,
|
|
1104
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events
|
|
1105
|
+
>(
|
|
1106
|
+
config:
|
|
1107
|
+
& {
|
|
1108
|
+
readonly child: ChildMachine<
|
|
1109
|
+
Id,
|
|
1110
|
+
& Machine<
|
|
1111
|
+
States,
|
|
1112
|
+
Events,
|
|
1113
|
+
Input,
|
|
1114
|
+
UnhandledStates,
|
|
1115
|
+
E,
|
|
1116
|
+
R,
|
|
1117
|
+
InitialE,
|
|
1118
|
+
InitialR,
|
|
1119
|
+
FinalStates,
|
|
1120
|
+
Output,
|
|
1121
|
+
Emits,
|
|
1122
|
+
OutputStates,
|
|
1123
|
+
InputEvents
|
|
1124
|
+
>
|
|
1125
|
+
& EnsureExecutable<States, UnhandledStates, OutputStates>
|
|
1126
|
+
>
|
|
1127
|
+
readonly snapshot?: (
|
|
1128
|
+
context: Machine.InvokeSnapshotContext<
|
|
1129
|
+
Machine.Snapshot<States>,
|
|
1130
|
+
| E
|
|
1131
|
+
| ActionError<R>
|
|
1132
|
+
| InfiniteTransitionError
|
|
1133
|
+
| MachineSchemaDecodeError
|
|
1134
|
+
| StoppedError,
|
|
1135
|
+
Output
|
|
1136
|
+
>
|
|
1137
|
+
) => SnapshotEvent | undefined
|
|
1138
|
+
readonly onDone: (context: Machine.InvokeDoneContext<Output>) => DoneEvent | undefined
|
|
1139
|
+
}
|
|
1140
|
+
& InvokeMachineInput<Input>
|
|
1141
|
+
): Machine.InvokeConfig<
|
|
1142
|
+
any,
|
|
1143
|
+
any,
|
|
1144
|
+
any,
|
|
1145
|
+
any,
|
|
1146
|
+
SnapshotEvent,
|
|
1147
|
+
Machine.Snapshot<States>,
|
|
1148
|
+
Machine.EventOf<InputEvents>,
|
|
1149
|
+
E | ActionError<R> | InfiniteTransitionError | MachineSchemaDecodeError | StoppedError,
|
|
1150
|
+
ExcludeCompatibleRuntime<
|
|
1151
|
+
Exclude<ExecutionServices<InitialR | R>, internalRuntime.MachineRuntime>,
|
|
1152
|
+
Machine.EventOf<Events>,
|
|
1153
|
+
Machine.EmitOf<Emits>
|
|
1154
|
+
>,
|
|
1155
|
+
Output,
|
|
1156
|
+
| InitialE
|
|
1157
|
+
| E
|
|
1158
|
+
| ActionError<InitialR | R>
|
|
1159
|
+
| InfiniteTransitionError
|
|
1160
|
+
| MachineSchemaDecodeError
|
|
1161
|
+
| StartupError
|
|
1162
|
+
| StoppedError,
|
|
1163
|
+
Machine.EmitOf<Emits>,
|
|
1164
|
+
DoneEvent
|
|
1165
|
+
>
|
|
1166
|
+
<
|
|
1167
|
+
const States extends Machine.StateSchemas,
|
|
1168
|
+
const Events extends ReadonlyArray<Machine.TaggedSchema>,
|
|
1169
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
|
|
1170
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
1171
|
+
UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
|
|
1172
|
+
E = never,
|
|
1173
|
+
R = never,
|
|
1174
|
+
InitialE = never,
|
|
1175
|
+
InitialR = never,
|
|
1176
|
+
FinalStates extends Machine.StateIdentifier<States> = never,
|
|
1177
|
+
Output = never,
|
|
1178
|
+
SnapshotEvent = never,
|
|
1179
|
+
Id extends string = string,
|
|
1180
|
+
OutputStates extends Machine.StateIdentifier<States> = never,
|
|
1181
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events
|
|
1182
|
+
>(
|
|
1183
|
+
config:
|
|
1184
|
+
& {
|
|
1185
|
+
readonly child: ChildMachine<
|
|
1186
|
+
Id,
|
|
1187
|
+
& Machine<
|
|
1188
|
+
States,
|
|
1189
|
+
Events,
|
|
1190
|
+
Input,
|
|
1191
|
+
UnhandledStates,
|
|
1192
|
+
E,
|
|
1193
|
+
R,
|
|
1194
|
+
InitialE,
|
|
1195
|
+
InitialR,
|
|
1196
|
+
FinalStates,
|
|
1197
|
+
Output,
|
|
1198
|
+
Emits,
|
|
1199
|
+
OutputStates,
|
|
1200
|
+
InputEvents
|
|
1201
|
+
>
|
|
1202
|
+
& EnsureExecutable<States, UnhandledStates, OutputStates>
|
|
1203
|
+
>
|
|
1204
|
+
readonly snapshot?: (
|
|
1205
|
+
context: Machine.InvokeSnapshotContext<
|
|
1206
|
+
Machine.Snapshot<States>,
|
|
1207
|
+
| E
|
|
1208
|
+
| ActionError<R>
|
|
1209
|
+
| InfiniteTransitionError
|
|
1210
|
+
| MachineSchemaDecodeError
|
|
1211
|
+
| StoppedError,
|
|
1212
|
+
Output
|
|
1213
|
+
>
|
|
1214
|
+
) => SnapshotEvent | undefined
|
|
1215
|
+
readonly onDone?: never
|
|
1216
|
+
}
|
|
1217
|
+
& InvokeMachineInput<Input>
|
|
1218
|
+
): Machine.InvokeConfig<
|
|
1219
|
+
any,
|
|
1220
|
+
any,
|
|
1221
|
+
any,
|
|
1222
|
+
any,
|
|
1223
|
+
SnapshotEvent,
|
|
1224
|
+
Machine.Snapshot<States>,
|
|
1225
|
+
Machine.EventOf<InputEvents>,
|
|
1226
|
+
E | ActionError<R> | InfiniteTransitionError | MachineSchemaDecodeError | StoppedError,
|
|
1227
|
+
ExcludeCompatibleRuntime<
|
|
1228
|
+
Exclude<ExecutionServices<InitialR | R>, internalRuntime.MachineRuntime>,
|
|
1229
|
+
Machine.EventOf<Events>,
|
|
1230
|
+
Machine.EmitOf<Emits>
|
|
1231
|
+
>,
|
|
1232
|
+
Output,
|
|
1233
|
+
| InitialE
|
|
1234
|
+
| E
|
|
1235
|
+
| ActionError<InitialR | R>
|
|
1236
|
+
| InfiniteTransitionError
|
|
1237
|
+
| MachineSchemaDecodeError
|
|
1238
|
+
| StartupError
|
|
1239
|
+
| StoppedError,
|
|
1240
|
+
Machine.EmitOf<Emits>
|
|
1241
|
+
>
|
|
1242
|
+
} = ((config: {
|
|
1243
|
+
readonly child: ChildMachine.Any
|
|
1244
|
+
readonly input?: unknown
|
|
1245
|
+
readonly snapshot?: (context: Machine.InvokeSnapshotContext<any, any, any>) => unknown
|
|
1246
|
+
readonly onDone?: (context: Machine.InvokeDoneContext<any>) => unknown
|
|
1247
|
+
}) => {
|
|
1248
|
+
const machine = config.child.machine
|
|
1249
|
+
// An invoke descriptor fixes both its machine and input. Compile its process
|
|
1250
|
+
// logic once; all mutable execution state belongs to the process instance.
|
|
1251
|
+
const logic = machine.input === undefined
|
|
1252
|
+
? (internalProcess.toProcessLogic as any)(machine)
|
|
1253
|
+
: (internalProcess.toProcessLogic as any)(machine, config.input)
|
|
1254
|
+
return {
|
|
1255
|
+
id: config.child.id,
|
|
1256
|
+
address: config.child.id,
|
|
1257
|
+
descriptor: config.child,
|
|
1258
|
+
src: () => logic,
|
|
1259
|
+
snapshot: config.snapshot,
|
|
1260
|
+
onDone: config.onDone,
|
|
1261
|
+
[Activities.ActivityMetadataTypeId]: {
|
|
1262
|
+
type: "machine",
|
|
1263
|
+
child: {
|
|
1264
|
+
id: config.child.id,
|
|
1265
|
+
machineId: machine.id ?? null
|
|
1266
|
+
}
|
|
1267
|
+
},
|
|
1268
|
+
[InvokeTypeId]: undefined as any
|
|
1269
|
+
}
|
|
1270
|
+
}) as any
|
|
1271
|
+
|
|
1272
|
+
export const planInitial: <
|
|
1273
|
+
const States extends Machine.StateSchemas,
|
|
1274
|
+
const Events extends ReadonlyArray<Machine.TaggedSchema>,
|
|
1275
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
|
|
1276
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
1277
|
+
UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
|
|
1278
|
+
E = never,
|
|
1279
|
+
R = never,
|
|
1280
|
+
InitialE = never,
|
|
1281
|
+
InitialR = never,
|
|
1282
|
+
FinalStates extends Machine.StateIdentifier<States> = never,
|
|
1283
|
+
Output = never,
|
|
1284
|
+
OutputStates extends Machine.StateIdentifier<States> = never,
|
|
1285
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events
|
|
1286
|
+
>(
|
|
1287
|
+
machine:
|
|
1288
|
+
& Machine<
|
|
1289
|
+
States,
|
|
1290
|
+
Events,
|
|
1291
|
+
Input,
|
|
1292
|
+
UnhandledStates,
|
|
1293
|
+
E,
|
|
1294
|
+
R,
|
|
1295
|
+
InitialE,
|
|
1296
|
+
InitialR,
|
|
1297
|
+
FinalStates,
|
|
1298
|
+
Output,
|
|
1299
|
+
Emits,
|
|
1300
|
+
OutputStates,
|
|
1301
|
+
InputEvents
|
|
1302
|
+
>
|
|
1303
|
+
& EnsureExecutable<States, UnhandledStates, OutputStates>,
|
|
1304
|
+
...args: [...Machine.InputArgs<Input>]
|
|
1305
|
+
) => Effect.Effect<
|
|
1306
|
+
& {
|
|
1307
|
+
readonly startingState: Machine.Snapshot<States>
|
|
1308
|
+
readonly initialEntryPaths: ReadonlyArray<Machine.StateIdentifier<States>>
|
|
1309
|
+
readonly state: Machine.Snapshot<States>
|
|
1310
|
+
readonly commands: ReadonlyArray<Command>
|
|
1311
|
+
readonly emittedEvents: ReadonlyArray<Machine.EmitOf<Emits>>
|
|
1312
|
+
readonly microsteps: ReadonlyArray<{
|
|
1313
|
+
readonly next: Machine.Snapshot<States>
|
|
1314
|
+
readonly event: Machine.EventOf<Events> | InitialEventModel
|
|
1315
|
+
readonly transitions: ReadonlyArray<
|
|
1316
|
+
Machine.RetainedTransition<
|
|
1317
|
+
Machine.StateNodeIdentifier<States>,
|
|
1318
|
+
Machine.TagOf<Events[number]>,
|
|
1319
|
+
Machine.StateNodeIdentifier<States>
|
|
1320
|
+
>
|
|
1321
|
+
>
|
|
1322
|
+
readonly commands: ReadonlyArray<Command>
|
|
1323
|
+
readonly raisedEvents: ReadonlyArray<Machine.EventOf<Events>>
|
|
1324
|
+
readonly emittedEvents: ReadonlyArray<Machine.EmitOf<Emits>>
|
|
1325
|
+
readonly exitPaths: ReadonlyArray<string>
|
|
1326
|
+
readonly entryPaths: ReadonlyArray<string>
|
|
1327
|
+
readonly changed: boolean
|
|
1328
|
+
}>
|
|
1329
|
+
}
|
|
1330
|
+
& (
|
|
1331
|
+
| {
|
|
1332
|
+
readonly done: true
|
|
1333
|
+
readonly output: Output
|
|
1334
|
+
}
|
|
1335
|
+
| {
|
|
1336
|
+
readonly done: false
|
|
1337
|
+
readonly output: undefined
|
|
1338
|
+
}
|
|
1339
|
+
),
|
|
1340
|
+
InitialE | E | InfiniteTransitionError | MachineSchemaDecodeError | StartupError,
|
|
1341
|
+
never
|
|
1342
|
+
> = internalPlanner.planInitial as any
|
|
1343
|
+
|
|
1344
|
+
export const stateNodes = <M extends Machine.Any>(
|
|
1345
|
+
machine: M
|
|
1346
|
+
): ReadonlyArray<
|
|
1347
|
+
Machine.StateNode<
|
|
1348
|
+
Machine.StateIdentifier<Machine.States<M>>,
|
|
1349
|
+
Machine.HistoryIdentifier<Machine.States<M>>,
|
|
1350
|
+
Machine.ChoiceIdentifier<Machine.States<M>>
|
|
1351
|
+
>
|
|
1352
|
+
> =>
|
|
1353
|
+
Array.from(machine.stateNodes.byPath.values()) as unknown as ReadonlyArray<
|
|
1354
|
+
Machine.StateNode<
|
|
1355
|
+
Machine.StateIdentifier<Machine.States<M>>,
|
|
1356
|
+
Machine.HistoryIdentifier<Machine.States<M>>,
|
|
1357
|
+
Machine.ChoiceIdentifier<Machine.States<M>>
|
|
1358
|
+
>
|
|
1359
|
+
>
|
|
1360
|
+
|
|
1361
|
+
export const transitionDefinitions = <M extends Machine.Any>(
|
|
1362
|
+
machine: M
|
|
1363
|
+
): ReadonlyArray<
|
|
1364
|
+
Machine.TransitionDefinition<
|
|
1365
|
+
Machine.StateNodeIdentifier<Machine.States<M>>,
|
|
1366
|
+
Machine.TagOf<Machine.Events<M>[number]>,
|
|
1367
|
+
Machine.StateNodeIdentifier<Machine.States<M>>
|
|
1368
|
+
>
|
|
1369
|
+
> =>
|
|
1370
|
+
Topology.transitionDefinitions(machine) as ReadonlyArray<
|
|
1371
|
+
Machine.TransitionDefinition<
|
|
1372
|
+
Machine.StateNodeIdentifier<Machine.States<M>>,
|
|
1373
|
+
Machine.TagOf<Machine.Events<M>[number]>,
|
|
1374
|
+
Machine.StateNodeIdentifier<Machine.States<M>>
|
|
1375
|
+
>
|
|
1376
|
+
>
|
|
1377
|
+
|
|
1378
|
+
export const activityDefinitions = <M extends Machine.Any>(
|
|
1379
|
+
machine: M
|
|
1380
|
+
): ReadonlyArray<Machine.ActivityDefinition<Machine.StateIdentifier<Machine.States<M>>>> =>
|
|
1381
|
+
Activities.activityDefinitions(machine) as ReadonlyArray<
|
|
1382
|
+
Machine.ActivityDefinition<Machine.StateIdentifier<Machine.States<M>>>
|
|
1383
|
+
>
|
|
1384
|
+
|
|
1385
|
+
export const configuration = <M extends Machine.Any>(
|
|
1386
|
+
machine: M,
|
|
1387
|
+
state: Machine.Snapshot<Machine.States<M>>
|
|
1388
|
+
): ReadonlyArray<
|
|
1389
|
+
Machine.ActiveStateNode<
|
|
1390
|
+
Machine.StateIdentifier<Machine.States<M>>,
|
|
1391
|
+
Machine.ChoiceIdentifier<Machine.States<M>>
|
|
1392
|
+
>
|
|
1393
|
+
> => {
|
|
1394
|
+
const active = Configuration.normalizeConfiguration(machine, state).active
|
|
1395
|
+
return stateNodes(machine).filter(
|
|
1396
|
+
(node): node is Machine.ActiveStateNode<
|
|
1397
|
+
Machine.StateIdentifier<Machine.States<M>>,
|
|
1398
|
+
Machine.ChoiceIdentifier<Machine.States<M>>
|
|
1399
|
+
> => node.type !== "history" && node.type !== "choice" && active.has(node.path)
|
|
1400
|
+
)
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
export const enabled = <
|
|
1404
|
+
const States extends Machine.StateSchemas,
|
|
1405
|
+
const Events extends ReadonlyArray<Machine.TaggedSchema>,
|
|
1406
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema>,
|
|
1407
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
1408
|
+
UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
|
|
1409
|
+
E = never,
|
|
1410
|
+
R = never,
|
|
1411
|
+
InitialE = never,
|
|
1412
|
+
InitialR = never,
|
|
1413
|
+
FinalStates extends Machine.StateIdentifier<States> = never,
|
|
1414
|
+
Output = never,
|
|
1415
|
+
OutputStates extends Machine.StateIdentifier<States> = never,
|
|
1416
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events
|
|
1417
|
+
>(
|
|
1418
|
+
machine: Machine<
|
|
1419
|
+
States,
|
|
1420
|
+
Events,
|
|
1421
|
+
Input,
|
|
1422
|
+
UnhandledStates,
|
|
1423
|
+
E,
|
|
1424
|
+
R,
|
|
1425
|
+
InitialE,
|
|
1426
|
+
InitialR,
|
|
1427
|
+
FinalStates,
|
|
1428
|
+
Output,
|
|
1429
|
+
Emits,
|
|
1430
|
+
OutputStates,
|
|
1431
|
+
InputEvents
|
|
1432
|
+
>,
|
|
1433
|
+
state: Machine.Snapshot<States>
|
|
1434
|
+
): ReadonlyArray<Machine.TagOf<Events[number]>> => internalPlanner.enabled(machine as any, state)
|
|
1435
|
+
|
|
1436
|
+
export const plan: <
|
|
1437
|
+
const States extends Machine.StateSchemas,
|
|
1438
|
+
const Events extends ReadonlyArray<Machine.TaggedSchema>,
|
|
1439
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
|
|
1440
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
1441
|
+
UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
|
|
1442
|
+
E = never,
|
|
1443
|
+
R = never,
|
|
1444
|
+
InitialE = never,
|
|
1445
|
+
InitialR = never,
|
|
1446
|
+
FinalStates extends Machine.StateIdentifier<States> = never,
|
|
1447
|
+
Output = never,
|
|
1448
|
+
OutputStates extends Machine.StateIdentifier<States> = never,
|
|
1449
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events
|
|
1450
|
+
>(
|
|
1451
|
+
machine:
|
|
1452
|
+
& Machine<
|
|
1453
|
+
States,
|
|
1454
|
+
Events,
|
|
1455
|
+
Input,
|
|
1456
|
+
UnhandledStates,
|
|
1457
|
+
E,
|
|
1458
|
+
R,
|
|
1459
|
+
InitialE,
|
|
1460
|
+
InitialR,
|
|
1461
|
+
FinalStates,
|
|
1462
|
+
Output,
|
|
1463
|
+
Emits,
|
|
1464
|
+
OutputStates,
|
|
1465
|
+
InputEvents
|
|
1466
|
+
>
|
|
1467
|
+
& EnsureExecutable<States, UnhandledStates, OutputStates>,
|
|
1468
|
+
state: Machine.Snapshot<States>,
|
|
1469
|
+
event: Machine.EventOf<InputEvents>
|
|
1470
|
+
) => Effect.Effect<
|
|
1471
|
+
& {
|
|
1472
|
+
readonly next: Machine.Snapshot<States>
|
|
1473
|
+
readonly commands: ReadonlyArray<Command>
|
|
1474
|
+
readonly emittedEvents: ReadonlyArray<Machine.EmitOf<Emits>>
|
|
1475
|
+
readonly microsteps: ReadonlyArray<{
|
|
1476
|
+
readonly next: Machine.Snapshot<States>
|
|
1477
|
+
readonly event: Machine.EventOf<Events> | InitialEventModel
|
|
1478
|
+
readonly transitions: ReadonlyArray<
|
|
1479
|
+
Machine.RetainedTransition<
|
|
1480
|
+
Machine.StateNodeIdentifier<States>,
|
|
1481
|
+
Machine.TagOf<Events[number]>,
|
|
1482
|
+
Machine.StateNodeIdentifier<States>
|
|
1483
|
+
>
|
|
1484
|
+
>
|
|
1485
|
+
readonly commands: ReadonlyArray<Command>
|
|
1486
|
+
readonly raisedEvents: ReadonlyArray<Machine.EventOf<Events>>
|
|
1487
|
+
readonly emittedEvents: ReadonlyArray<Machine.EmitOf<Emits>>
|
|
1488
|
+
readonly exitPaths: ReadonlyArray<string>
|
|
1489
|
+
readonly entryPaths: ReadonlyArray<string>
|
|
1490
|
+
readonly changed: boolean
|
|
1491
|
+
}>
|
|
1492
|
+
}
|
|
1493
|
+
& (
|
|
1494
|
+
| {
|
|
1495
|
+
readonly done: true
|
|
1496
|
+
readonly output: Output
|
|
1497
|
+
}
|
|
1498
|
+
| {
|
|
1499
|
+
readonly done: false
|
|
1500
|
+
readonly output: undefined
|
|
1501
|
+
}
|
|
1502
|
+
),
|
|
1503
|
+
E | InfiniteTransitionError | MachineSchemaDecodeError,
|
|
1504
|
+
never
|
|
1505
|
+
> = internalPlanner.plan as any
|
|
1506
|
+
|
|
1507
|
+
export const effect = <Output, Error = never, Requirements = never>(
|
|
1508
|
+
effect: Effect.Effect<Output, Error, Requirements>
|
|
1509
|
+
): Logic<void, never, Error, Requirements, Output> => ({
|
|
1510
|
+
initial: () => Effect.void,
|
|
1511
|
+
run: () => effect
|
|
1512
|
+
})
|
|
1513
|
+
|
|
1514
|
+
export const logic = <
|
|
1515
|
+
State,
|
|
1516
|
+
Event = never,
|
|
1517
|
+
Output = void,
|
|
1518
|
+
Error = never,
|
|
1519
|
+
Requirements = never,
|
|
1520
|
+
InitialError = never,
|
|
1521
|
+
InitialRequirements = never
|
|
1522
|
+
>(
|
|
1523
|
+
options: {
|
|
1524
|
+
readonly initial:
|
|
1525
|
+
| State
|
|
1526
|
+
| ((
|
|
1527
|
+
scope: Logic.Scope<Event>
|
|
1528
|
+
) => Effect.Effect<State, InitialError, InitialRequirements>)
|
|
1529
|
+
readonly run: (
|
|
1530
|
+
context: Logic.Context<State, Event>
|
|
1531
|
+
) => Effect.Effect<Output, Error, Requirements>
|
|
1532
|
+
}
|
|
1533
|
+
): Logic<State, Event, Error, Requirements | InitialRequirements, Output, InitialError> => ({
|
|
1534
|
+
initial: (scope) =>
|
|
1535
|
+
typeof options.initial === "function"
|
|
1536
|
+
? (options.initial as (
|
|
1537
|
+
scope: Logic.Scope<Event>
|
|
1538
|
+
) => Effect.Effect<State, InitialError, InitialRequirements>)(scope)
|
|
1539
|
+
: Effect.succeed(options.initial),
|
|
1540
|
+
run: options.run
|
|
1541
|
+
})
|
|
1542
|
+
|
|
1543
|
+
export const transition = <State, Event, Error = never, Requirements = never>(
|
|
1544
|
+
initial: State,
|
|
1545
|
+
transition: (state: State, event: Event) => Effect.Effect<State, Error, Requirements>
|
|
1546
|
+
): Logic<State, Event, Error, Requirements, never> =>
|
|
1547
|
+
logic<State, Event, never, Error, Requirements>({
|
|
1548
|
+
initial,
|
|
1549
|
+
run: ({ receive, updateState }) =>
|
|
1550
|
+
receive.pipe(
|
|
1551
|
+
Effect.flatMap((event) => updateState((state) => transition(state, event))),
|
|
1552
|
+
Effect.forever
|
|
1553
|
+
)
|
|
1554
|
+
})
|
|
1555
|
+
|
|
1556
|
+
export const child = <const Id extends string, M extends Machine.Any>(
|
|
1557
|
+
id: Id,
|
|
1558
|
+
machine: M
|
|
1559
|
+
): ChildMachine<Id, M> => ({
|
|
1560
|
+
[ChildMachineTypeId]: ChildMachineTypeId,
|
|
1561
|
+
id,
|
|
1562
|
+
machine
|
|
1563
|
+
})
|
|
1564
|
+
|
|
1565
|
+
export const childAddress = <Event = never>(id: string): ChildAddress<Event> => id as ChildAddress<Event>
|
|
1566
|
+
|
|
1567
|
+
export const spawn: {
|
|
1568
|
+
<ChildState, ChildEvent, ChildError, ChildRequirements, ChildOutput, ChildInitialError = never>(
|
|
1569
|
+
logic: Logic<
|
|
1570
|
+
ChildState,
|
|
1571
|
+
ChildEvent,
|
|
1572
|
+
ChildError,
|
|
1573
|
+
ChildRequirements,
|
|
1574
|
+
ChildOutput,
|
|
1575
|
+
ChildInitialError
|
|
1576
|
+
>
|
|
1577
|
+
): SpawnResult<ChildState, ChildEvent, ChildError, ChildRequirements, ChildOutput, never, ChildInitialError>
|
|
1578
|
+
<
|
|
1579
|
+
ChildState,
|
|
1580
|
+
ChildEvent,
|
|
1581
|
+
ChildError,
|
|
1582
|
+
ChildRequirements,
|
|
1583
|
+
ChildOutput,
|
|
1584
|
+
Options extends SpawnOptions,
|
|
1585
|
+
ChildInitialError = never
|
|
1586
|
+
>(
|
|
1587
|
+
logic: Logic<
|
|
1588
|
+
ChildState,
|
|
1589
|
+
ChildEvent,
|
|
1590
|
+
ChildError,
|
|
1591
|
+
ChildRequirements,
|
|
1592
|
+
ChildOutput,
|
|
1593
|
+
ChildInitialError
|
|
1594
|
+
>,
|
|
1595
|
+
options: Options & ChildAddress.OptionsCompatibility<Options, ChildEvent>
|
|
1596
|
+
): SpawnResult<
|
|
1597
|
+
ChildState,
|
|
1598
|
+
ChildEvent,
|
|
1599
|
+
ChildError,
|
|
1600
|
+
ChildRequirements,
|
|
1601
|
+
ChildOutput,
|
|
1602
|
+
SpawnError<Options>,
|
|
1603
|
+
ChildInitialError
|
|
1604
|
+
>
|
|
1605
|
+
} = ((
|
|
1606
|
+
logic: Logic<any, any, any, any, any, any>,
|
|
1607
|
+
options?: SpawnOptions
|
|
1608
|
+
) =>
|
|
1609
|
+
Effect.flatMap(
|
|
1610
|
+
internalRuntime.MachineRuntime,
|
|
1611
|
+
(runtime) => options === undefined ? runtime.spawn(logic) : (runtime.spawn as any)(logic, options)
|
|
1612
|
+
)) as any
|
|
1613
|
+
|
|
1614
|
+
export const sendTo: {
|
|
1615
|
+
<Child extends ChildMachine.Any>(
|
|
1616
|
+
child: Child,
|
|
1617
|
+
event: ChildMachine.Event<Child>
|
|
1618
|
+
): Effect.Effect<void, StoppedError, MachineRuntimeRequirement>
|
|
1619
|
+
<Address extends ChildAddress<never>>(
|
|
1620
|
+
id: Address,
|
|
1621
|
+
event: ChildAddress.Event<Address>
|
|
1622
|
+
): Effect.Effect<void, StoppedError, MachineRuntimeRequirement>
|
|
1623
|
+
} = ((child: string | ChildMachine.Any, event: unknown) =>
|
|
1624
|
+
Effect.flatMap(
|
|
1625
|
+
internalRuntime.MachineRuntime,
|
|
1626
|
+
(runtime) => runtime.sendTo(child, event)
|
|
1627
|
+
)) as any
|
|
1628
|
+
|
|
1629
|
+
export const stopChild: {
|
|
1630
|
+
<Event>(child: ChildAddress<Event>): Effect.Effect<void, never, MachineRuntimeRequirement>
|
|
1631
|
+
<Child extends ChildMachine.Any>(child: Child): Effect.Effect<void, never, MachineRuntimeRequirement>
|
|
1632
|
+
} = ((child: string | ChildMachine.Any) =>
|
|
1633
|
+
Effect.flatMap(
|
|
1634
|
+
internalRuntime.MachineRuntime,
|
|
1635
|
+
(runtime) => runtime.stopChild(child)
|
|
1636
|
+
)) as any
|
|
1637
|
+
|
|
1638
|
+
export const watch = <State, Event, Error = never, Output = never>(
|
|
1639
|
+
ref: MachineRef<State, Event, Error, Output>
|
|
1640
|
+
): Stream.Stream<RuntimeOutcome<State, Error, Output>> => internalRuntime.watch(ref)
|
|
1641
|
+
|
|
1642
|
+
export const start: <
|
|
1643
|
+
const States extends Machine.StateSchemas,
|
|
1644
|
+
const Events extends ReadonlyArray<Machine.TaggedSchema>,
|
|
1645
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
|
|
1646
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
1647
|
+
UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
|
|
1648
|
+
E = never,
|
|
1649
|
+
R = never,
|
|
1650
|
+
InitialE = never,
|
|
1651
|
+
InitialR = never,
|
|
1652
|
+
FinalStates extends Machine.StateIdentifier<States> = never,
|
|
1653
|
+
Output = never,
|
|
1654
|
+
OutputStates extends Machine.StateIdentifier<States> = never,
|
|
1655
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events
|
|
1656
|
+
>(
|
|
1657
|
+
machine:
|
|
1658
|
+
& Machine<
|
|
1659
|
+
States,
|
|
1660
|
+
Events,
|
|
1661
|
+
Input,
|
|
1662
|
+
UnhandledStates,
|
|
1663
|
+
E,
|
|
1664
|
+
R,
|
|
1665
|
+
InitialE,
|
|
1666
|
+
InitialR,
|
|
1667
|
+
FinalStates,
|
|
1668
|
+
Output,
|
|
1669
|
+
Emits,
|
|
1670
|
+
OutputStates,
|
|
1671
|
+
InputEvents
|
|
1672
|
+
>
|
|
1673
|
+
& EnsureExecutable<States, UnhandledStates, OutputStates>,
|
|
1674
|
+
...args: [...Machine.InputArgs<Input>]
|
|
1675
|
+
) => Effect.Effect<
|
|
1676
|
+
MachineRef<
|
|
1677
|
+
Machine.Snapshot<States>,
|
|
1678
|
+
Machine.EventOf<InputEvents>,
|
|
1679
|
+
| E
|
|
1680
|
+
| ActionError<R>
|
|
1681
|
+
| InfiniteTransitionError
|
|
1682
|
+
| MachineSchemaDecodeError
|
|
1683
|
+
| StoppedError,
|
|
1684
|
+
Output
|
|
1685
|
+
>,
|
|
1686
|
+
| InitialE
|
|
1687
|
+
| E
|
|
1688
|
+
| ActionError<InitialR | R>
|
|
1689
|
+
| InfiniteTransitionError
|
|
1690
|
+
| MachineSchemaDecodeError
|
|
1691
|
+
| StartupError
|
|
1692
|
+
| StoppedError,
|
|
1693
|
+
ExcludeCompatibleRuntime<
|
|
1694
|
+
ExecutionServices<InitialR | R>,
|
|
1695
|
+
Machine.EventOf<Events>,
|
|
1696
|
+
Machine.EmitOf<Emits>
|
|
1697
|
+
>
|
|
1698
|
+
> = internalProcess.start as any
|
|
1699
|
+
|
|
1700
|
+
export const resume: <
|
|
1701
|
+
const States extends Machine.StateSchemas,
|
|
1702
|
+
const Events extends ReadonlyArray<Machine.TaggedSchema>,
|
|
1703
|
+
const Emits extends ReadonlyArray<Machine.TaggedSchema> = readonly [],
|
|
1704
|
+
const Input extends Schema.Top = typeof Schema.Void,
|
|
1705
|
+
UnhandledStates extends Machine.StateIdentifier<States> = Machine.StateIdentifier<States>,
|
|
1706
|
+
E = never,
|
|
1707
|
+
R = never,
|
|
1708
|
+
InitialE = never,
|
|
1709
|
+
InitialR = never,
|
|
1710
|
+
FinalStates extends Machine.StateIdentifier<States> = never,
|
|
1711
|
+
Output = never,
|
|
1712
|
+
OutputStates extends Machine.StateIdentifier<States> = never,
|
|
1713
|
+
InputEvents extends ReadonlyArray<Machine.TaggedSchema> = Events
|
|
1714
|
+
>(
|
|
1715
|
+
machine:
|
|
1716
|
+
& Machine<
|
|
1717
|
+
States,
|
|
1718
|
+
Events,
|
|
1719
|
+
Input,
|
|
1720
|
+
UnhandledStates,
|
|
1721
|
+
E,
|
|
1722
|
+
R,
|
|
1723
|
+
InitialE,
|
|
1724
|
+
InitialR,
|
|
1725
|
+
FinalStates,
|
|
1726
|
+
Output,
|
|
1727
|
+
Emits,
|
|
1728
|
+
OutputStates,
|
|
1729
|
+
InputEvents
|
|
1730
|
+
>
|
|
1731
|
+
& EnsureExecutable<States, UnhandledStates, OutputStates>,
|
|
1732
|
+
snapshot: Machine.Snapshot<States>
|
|
1733
|
+
) => Effect.Effect<
|
|
1734
|
+
MachineRef<
|
|
1735
|
+
Machine.Snapshot<States>,
|
|
1736
|
+
Machine.EventOf<InputEvents>,
|
|
1737
|
+
| E
|
|
1738
|
+
| ActionError<R>
|
|
1739
|
+
| InfiniteTransitionError
|
|
1740
|
+
| MachineSchemaDecodeError
|
|
1741
|
+
| StoppedError,
|
|
1742
|
+
Output
|
|
1743
|
+
>,
|
|
1744
|
+
MachineSchemaDecodeError,
|
|
1745
|
+
ExcludeCompatibleRuntime<
|
|
1746
|
+
ExecutionServices<R>,
|
|
1747
|
+
Machine.EventOf<Events>,
|
|
1748
|
+
Machine.EmitOf<Emits>
|
|
1749
|
+
>
|
|
1750
|
+
> = internalProcess.resume as any
|