diff --git a/Sources/RecombinePackage/Store/BaseStore.swift b/Sources/RecombinePackage/Store/BaseStore.swift index 96afee5..a734eb3 100644 --- a/Sources/RecombinePackage/Store/BaseStore.swift +++ b/Sources/RecombinePackage/Store/BaseStore.swift @@ -4,25 +4,19 @@ public class BaseStore: StoreProtoco public typealias SubState = State public typealias SubRefinedAction = RefinedAction public typealias Action = ActionStrata + public typealias ActionsAndState = ([RefinedAction], (previous: State, current: State)) @Published public private(set) var state: State public var statePublisher: Published.Publisher { $state } public var underlying: BaseStore { self } public let stateLens: (State) -> State = { $0 } - public let rawActions = PassthroughSubject() - public let preMiddlewareRefinedActions = PassthroughSubject<[RefinedAction], Never>() - public let postMiddlewareRefinedActions = PassthroughSubject<[RefinedAction], Never>() - public let allStateUpdates = PassthroughSubject() - public let actionsPairedWithState = PassthroughSubject<([RefinedAction], (previous: State, current: State)), Never>() public let actionPromotion: (RefinedAction) -> RefinedAction = { $0 } - public var actions: AnyPublisher { - Publishers.Merge( - rawActions.map(Action.raw), - postMiddlewareRefinedActions.flatMap(\.publisher).map(Action.refined) - ) - .eraseToAnyPublisher() - } + private let _rawActions = PassthroughSubject() + private let _preMiddlewareRefinedActions = PassthroughSubject<[RefinedAction], Never>() + private let _postMiddlewareRefinedActions = PassthroughSubject<[RefinedAction], Never>() + private let _allStateUpdates = PassthroughSubject() + private let _actionsPairedWithState = PassthroughSubject() private var cancellables = Set() public init( @@ -34,7 +28,7 @@ public class BaseStore: StoreProtoco ) where R.State == State, R.Action == RefinedAction { self.state = state - rawActions.flatMap { [weak self] action in + _rawActions.flatMap { [weak self] action in self.publisher().flatMap { thunk.transform($0.$state.first(), action) } @@ -50,17 +44,17 @@ public class BaseStore: StoreProtoco .store(in: &cancellables) Publishers.Zip( - postMiddlewareRefinedActions, - allStateUpdates + _postMiddlewareRefinedActions, + _allStateUpdates .prepend(state) .scan([]) { acc, item in .init((acc + [item]).suffix(2)) } .filter { $0.count == 2 } .map { ($0[0], $0[1]) } ) - .sink(receiveValue: actionsPairedWithState.send) + .sink(receiveValue: _actionsPairedWithState.send) .store(in: &cancellables) - preMiddlewareRefinedActions + _preMiddlewareRefinedActions .flatMap { [weak self] actions in self.publisher() .flatMap { $0.$state.first() } @@ -72,18 +66,18 @@ public class BaseStore: StoreProtoco } } .sink(receiveValue: { [weak self] actions in - self?.postMiddlewareRefinedActions.send(actions) + self?._postMiddlewareRefinedActions.send(actions) }) .store(in: &cancellables) - postMiddlewareRefinedActions + _postMiddlewareRefinedActions .scan(state) { state, actions in actions.reduce(state, reducer.reduce) } .receive(on: scheduler) .sink { [weak self] state in guard let self = self else { return } - self.allStateUpdates.send(state) + self._allStateUpdates.send(state) if self.state != state { self.state = state } @@ -91,15 +85,43 @@ public class BaseStore: StoreProtoco .store(in: &cancellables) } + public var actions: AnyPublisher { + Publishers.Merge( + _rawActions.map(Action.raw), + _postMiddlewareRefinedActions.flatMap(\.publisher).map(Action.refined) + ) + .eraseToAnyPublisher() + } + + open var rawActions: AnyPublisher { + _rawActions.eraseToAnyPublisher() + } + + open var preMiddlewareRefinedActions: AnyPublisher<[RefinedAction], Never> { + _preMiddlewareRefinedActions.eraseToAnyPublisher() + } + + open var postMiddlewareRefinedActions: AnyPublisher<[RefinedAction], Never> { + _postMiddlewareRefinedActions.eraseToAnyPublisher() + } + + open var allStateUpdates: AnyPublisher { + _allStateUpdates.eraseToAnyPublisher() + } + + open var actionsPairedWithState: AnyPublisher { + _actionsPairedWithState.eraseToAnyPublisher() + } + open func dispatch(refined actions: S) where S.Element == RefinedAction { - preMiddlewareRefinedActions.send(.init(actions)) + _preMiddlewareRefinedActions.send(.init(actions)) } open func dispatch(raw actions: S) where S.Element == RawAction { - actions.forEach(rawActions.send) + actions.forEach(_rawActions.send) } open func injectBypassingMiddleware(actions: S) where S.Element == RefinedAction { - postMiddlewareRefinedActions.send(.init(actions)) + _postMiddlewareRefinedActions.send(.init(actions)) } } diff --git a/Sources/RecombinePackage/Store/LensedStore.swift b/Sources/RecombinePackage/Store/LensedStore.swift index 79c2f2c..da14e67 100644 --- a/Sources/RecombinePackage/Store/LensedStore.swift +++ b/Sources/RecombinePackage/Store/LensedStore.swift @@ -7,8 +7,9 @@ public class LensedStore.Publisher { $state } public let underlying: BaseStore public let stateLens: (BaseState) -> SubState - public let actions = PassthroughSubject<[SubRefinedAction], Never>() public let actionPromotion: (SubRefinedAction) -> BaseRefinedAction + + private let _actions = PassthroughSubject<[SubRefinedAction], Never>() private var cancellables = Set() public required init(store: StoreType, lensing lens: @escaping (BaseState) -> SubState, actionPromotion: @escaping (SubRefinedAction) -> BaseRefinedAction) { @@ -25,8 +26,12 @@ public class LensedStore { + _actions.eraseToAnyPublisher() + } + open func dispatch(refined actions: S) where S.Element == SubRefinedAction { - self.actions.send(.init(actions)) + _actions.send(.init(actions)) underlying.dispatch(refined: actions.map(actionPromotion)) }