Skip to content

Commit

Permalink
0.7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
dankinsoid committed Oct 5, 2023
1 parent 4e99a57 commit 062258d
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 13 deletions.
Binary file not shown.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ import PackageDescription
let package = Package(
name: "SomeProject",
dependencies: [
.package(url: "https://github.com/dankinsoid/VDStore.git", from: "0.6.0")
.package(url: "https://github.com/dankinsoid/VDStore.git", from: "0.7.0")
],
targets: [
.target(name: "SomeProject", dependencies: ["VDStore"])
Expand Down
20 changes: 17 additions & 3 deletions Sources/VDStore/Ref.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,24 @@ public struct Ref<State> {
setter = set
}

public func scope<ChildState>(_ keyPath: WritableKeyPath<State, ChildState>) -> Ref<ChildState> {
public func scope<ChildState>(
get childGet: @escaping (State) -> ChildState,
set childSet: @escaping (inout State, ChildState) -> Void
) -> Ref<ChildState> {
Ref<ChildState>(
get: { self.wrappedValue[keyPath: keyPath] },
set: { self.wrappedValue[keyPath: keyPath] = $0 }
get: { childGet(getter()) },
set: {
var state = getter()
childSet(&state, $0)
setter(state)
}
)
}

public func scope<ChildState>(_ keyPath: WritableKeyPath<State, ChildState>) -> Ref<ChildState> {
scope(
get: { $0[keyPath: keyPath] },
set: { $0[keyPath: keyPath] = $1 }
)
}

Expand Down
61 changes: 59 additions & 2 deletions Sources/VDStore/Store.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ public struct Store<State> {

@Ref public var state: State
public let publisher: AnyPublisher<State, Never>
public var dependencies: StoreDependencies
public var dependencies: StoreDependencies {
_dependencies.with(store: self)
}

private var _dependencies: StoreDependencies
private var values: [PartialKeyPath<Store>: Any]

public var wrappedValue: State {
Expand Down Expand Up @@ -64,10 +68,21 @@ public struct Store<State> {
) where P.Output == State, P.Failure == Never {
self._state = state
self.publisher = publisher.eraseToAnyPublisher()
self.dependencies = dependencies
self._dependencies = dependencies
self.values = values
}

public func scope<ChildState>(
get getter: @escaping (State) -> ChildState,
set setter: @escaping (inout State, ChildState) -> Void
) -> Store<ChildState> {
Store<ChildState>(
state: $state.scope(get: getter, set: setter),
publisher: publisher.map(getter),
dependencies: dependencies
)
}

public func scope<ChildState>(_ keyPath: WritableKeyPath<State, ChildState>) -> Store<ChildState> {
Store<ChildState>(
state: $state.scope(keyPath),
Expand Down Expand Up @@ -108,6 +123,19 @@ public struct Store<State> {
)
}

public func transformDependency(
_ transform: (inout StoreDependencies) -> Void
) -> Store {
var dependencies = self.dependencies
transform(&dependencies)
return Store(
state: $state,
publisher: publisher,
dependencies: dependencies,
values: values
)
}

public func modify(_ modifier: (inout State) -> Void) {
modifier(&state)
}
Expand All @@ -116,3 +144,32 @@ public struct Store<State> {
values[keyPath] as? Value
}
}

extension StoreDependencies {

private var stores: [ObjectIdentifier: Any] {
get { self[\.stores] ?? [:] }
set { self[\.stores] = newValue }
}

public func store<T>(
for type: T.Type,
defaultForLive live: @autoclosure () -> Store<T>,
test: @autoclosure () -> Store<T>? = nil,
preview: @autoclosure () -> Store<T>? = nil
) -> Store<T> {
(stores[ObjectIdentifier(type)] as? Store<T>) ?? defaultFor(
live: live(),
test: test(),
preview: preview()
)
}

public func with<T>(
store: Store<T>
) -> StoreDependencies {
transform(\.stores) { stores in
stores[ObjectIdentifier(T.self)] = store
}
}
}
24 changes: 17 additions & 7 deletions Sources/VDStore/StoreDependencies.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,37 @@ public struct StoreDependencies {
return new
}


public func transform<Dependency>(
_ keyPath: KeyPath<StoreDependencies, Dependency>,
_ transform: (inout Dependency) -> Void
) -> StoreDependencies {
var value = self[keyPath: keyPath]
transform(&value)
return with(keyPath, value)
}

public func merging(with dependencies: StoreDependencies) -> StoreDependencies {
var new = self
new.dependencies.merge(dependencies.dependencies) { _, new in new }
return new
}

public func defaultFor<Value>(
live: Value,
test: Value? = nil,
preview: Value? = nil
live: @autoclosure () -> Value,
test: @autoclosure () -> Value? = nil,
preview: @autoclosure () -> Value? = nil
) -> Value {
#if DEBUG
if _isPreview {
return preview ?? test ?? live
return preview() ?? test() ?? live()
} else if _XCTIsTesting {
return test ?? preview ?? live
return test() ?? preview() ?? live()
} else {
return live
return live()
}
#else
return live
return live()
#endif
}
}
Expand Down

0 comments on commit 062258d

Please sign in to comment.