Skip to content

Commit 6ed3c25

Browse files
committed
Merge remote-tracking branch 'origin/main' into jquadri/workflow-observers
* origin/main: [chore]: refactor some internal actions to use existential any (#190)
2 parents f92694c + f9f5494 commit 6ed3c25

File tree

3 files changed

+50
-19
lines changed

3 files changed

+50
-19
lines changed

Diff for: Workflow/Sources/SubtreeManager.swift

+11-7
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ extension WorkflowNode {
130130

131131
extension WorkflowNode.SubtreeManager {
132132
enum Output {
133-
case update(AnyWorkflowAction<WorkflowType>, source: WorkflowUpdateDebugInfo.Source)
133+
case update(any WorkflowAction<WorkflowType>, source: WorkflowUpdateDebugInfo.Source)
134134
case childDidUpdate(WorkflowUpdateDebugInfo)
135135
}
136136
}
@@ -209,7 +209,7 @@ extension WorkflowNode.SubtreeManager {
209209
/// Update the existing child
210210
existing.update(
211211
workflow: workflow,
212-
outputMap: { AnyWorkflowAction(outputMap($0)) },
212+
outputMap: { outputMap($0) },
213213
eventPipe: eventPipe
214214
)
215215
child = existing
@@ -218,7 +218,7 @@ extension WorkflowNode.SubtreeManager {
218218
/// This spins up a new workflow node, etc to host the newly created child.
219219
child = ChildWorkflow<Child>(
220220
workflow: workflow,
221-
outputMap: { AnyWorkflowAction(outputMap($0)) },
221+
outputMap: { outputMap($0) },
222222
eventPipe: eventPipe,
223223
key: key,
224224
parentSession: session,
@@ -333,7 +333,7 @@ extension WorkflowNode.SubtreeManager {
333333
var observerInfo: ObserverInfo?
334334

335335
func handle(action: Action) {
336-
let output = Output.update(AnyWorkflowAction(action), source: .external)
336+
let output = Output.update(action, source: .external)
337337

338338
if let observerInfo = observerInfo {
339339
observerInfo.observer.workflowDidReceiveAction(
@@ -456,11 +456,11 @@ extension WorkflowNode.SubtreeManager {
456456

457457
fileprivate final class ChildWorkflow<W: Workflow>: AnyChildWorkflow {
458458
private let node: WorkflowNode<W>
459-
private var outputMap: (W.Output) -> AnyWorkflowAction<WorkflowType>
459+
private var outputMap: (W.Output) -> any WorkflowAction<WorkflowType>
460460

461461
init(
462462
workflow: W,
463-
outputMap: @escaping (W.Output) -> AnyWorkflowAction<WorkflowType>,
463+
outputMap: @escaping (W.Output) -> any WorkflowAction<WorkflowType>,
464464
eventPipe: EventPipe,
465465
key: String,
466466
parentSession: WorkflowSession?,
@@ -489,7 +489,11 @@ extension WorkflowNode.SubtreeManager {
489489
return node.render(isRootNode: false)
490490
}
491491

492-
func update(workflow: W, outputMap: @escaping (W.Output) -> AnyWorkflowAction<WorkflowType>, eventPipe: EventPipe) {
492+
func update(
493+
workflow: W,
494+
outputMap: @escaping (W.Output) -> any WorkflowAction<WorkflowType>,
495+
eventPipe: EventPipe
496+
) {
493497
self.outputMap = outputMap
494498
self.eventPipe = eventPipe
495499
node.update(workflow: workflow)

Diff for: Workflow/Sources/WorkflowNode.swift

+38-11
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,15 @@ final class WorkflowNode<WorkflowType: Workflow> {
7979
let output: Output
8080

8181
switch subtreeOutput {
82-
case .update(let event, let source):
83-
let actionObserverCompletion = observer?.workflowWillApplyAction(
84-
event,
85-
workflow: workflow,
86-
state: state,
87-
session: session
82+
case .update(let action, let source):
83+
/// 'Opens' the existential `any WorkflowAction<WorkflowType>` value
84+
/// allowing the underlying conformance to be applied to the Workflow's State
85+
let outputEvent = openAndApply(
86+
action,
87+
to: &state,
88+
observerInfo: observer.map { ($0, workflow, session) }
8889
)
8990

90-
/// Apply the update to the current state
91-
let outputEvent = event.apply(toState: &state)
92-
9391
/// Finally, we tell the outside world that our state has changed (including an output event if it exists).
9492
output = Output(
9593
outputEvent: outputEvent,
@@ -99,8 +97,6 @@ final class WorkflowNode<WorkflowType: Workflow> {
9997
)
10098
)
10199

102-
actionObserverCompletion?(state, outputEvent)
103-
104100
case .childDidUpdate(let debugInfo):
105101
output = Output(
106102
outputEvent: nil,
@@ -181,3 +177,34 @@ extension WorkflowNode {
181177
var debugInfo: WorkflowUpdateDebugInfo
182178
}
183179
}
180+
181+
private extension WorkflowNode {
182+
/// Applies an appropriate `WorkflowAction` to advance the underlying Workflow `State`
183+
/// - Parameters:
184+
/// - action: The `WorkflowAction` to apply
185+
/// - state: The `State` to which the action will be applied
186+
/// - observerInfo: Optional observation info to notify registered `WorkflowObserver`s
187+
/// - Returns: An optional `Output` produced by the action application
188+
func openAndApply<A: WorkflowAction>(
189+
_ action: A,
190+
to state: inout WorkflowType.State,
191+
observerInfo: (WorkflowObserver, WorkflowType, WorkflowSession)?
192+
) -> WorkflowType.Output? where A.WorkflowType == WorkflowType {
193+
let output: WorkflowType.Output?
194+
195+
let observerCompletion = observerInfo.flatMap { observer, workflow, session in
196+
observer.workflowWillApplyAction(
197+
action,
198+
workflow: workflow,
199+
state: state,
200+
session: session
201+
)
202+
}
203+
defer { observerCompletion?(state, output) }
204+
205+
/// Apply the action to the current state
206+
output = action.apply(toState: &state)
207+
208+
return output
209+
}
210+
}

Diff for: Workflow/Tests/SubtreeManagerTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ final class SubtreeManagerTests: XCTestCase {
7272
manager.onUpdate = {
7373
switch $0 {
7474
case .update(let event, _):
75-
events.append(event)
75+
events.append(AnyWorkflowAction(event))
7676
default:
7777
break
7878
}

0 commit comments

Comments
 (0)