diff --git a/Decide-Tests/SwiftUI_Tests.swift b/Decide-Tests/SwiftUI_Tests.swift index 8934d92..bc92312 100644 --- a/Decide-Tests/SwiftUI_Tests.swift +++ b/Decide-Tests/SwiftUI_Tests.swift @@ -15,7 +15,6 @@ import SwiftUI import Decide import XCTest -import DecideTesting @MainActor final class SwiftUI_Tests: XCTestCase { @@ -33,8 +32,8 @@ import DecideTesting struct UpdateStr: ValueDecision { var newValue: String - func mutate(_ env: Decide.DecisionEnvironment) { -// env[\.Storage.$str] = newValue + func mutate(_ env: DecisionEnvironment) { + var x = env[\Storage.$str] } } diff --git a/Decide/Binding/Bind.swift b/Decide/Binding/Bind.swift index b5c5a66..5b915ed 100644 --- a/Decide/Binding/Bind.swift +++ b/Decide/Binding/Bind.swift @@ -47,23 +47,16 @@ public final class Bind where Root: StateRoot { get { let wrapperInstance = instance[keyPath: storageKeyPath] let root = wrapperInstance.environment.get(Root.self) - let observableValue = root[keyPath: wrapperInstance.statePath] - -#warning(""" -TODO: Squash updates of any values this instance is subscribed to, -to one update to instance. -""") - let observer = Observer(wrapperInstance) { [weak instance] in + let observableValue = root[keyPath: wrapperInstance.statePath.appending(path: \.storage)] + let observer = Observer(instance) { [weak instance] in instance?.onChange() } - - return observableValue.getValueSubscribing(observer: observer) } set { let wrapperInstance = instance[keyPath: storageKeyPath] let root = wrapperInstance.environment.get(Root.self) - let observableValue = root[keyPath: wrapperInstance.statePath] + let observableValue = root[keyPath: wrapperInstance.statePath.appending(path: \.storage)] observableValue.set(value: newValue) } } diff --git a/Decide/Binding/SwiftUIBinding.swift b/Decide/Binding/SwiftUIBinding.swift index eb1b0f3..e3b79c5 100644 --- a/Decide/Binding/SwiftUIBinding.swift +++ b/Decide/Binding/SwiftUIBinding.swift @@ -31,7 +31,7 @@ public struct SwiftUIBind< public var wrappedValue: Value { get { environment - .get(Root.self)[keyPath: statePath] + .get(Root.self)[keyPath: statePath.appending(path: \.storage)] .getValueSubscribing( observer: Observer(publisher) { [weak publisher] in publisher?.objectWillChange.send() @@ -40,7 +40,7 @@ public struct SwiftUIBind< } nonmutating set { environment - .get(Root.self)[keyPath: statePath] + .get(Root.self)[keyPath: statePath.appending(path: \.storage)] .set(value: newValue) } } diff --git a/Decide/Decision/Decision.swift b/Decide/Decision/Decision.swift index aacb327..6090071 100644 --- a/Decide/Decision/Decision.swift +++ b/Decide/Decision/Decision.swift @@ -51,38 +51,76 @@ public typealias EnvironmentMutation = (DecisionEnvironment) -> Void } func make(decision: Decision) { - /** - 1. Create a temporary environment, something to enable transactions - 2. Perform that mutation - 3. Execute effects - */ decision.mutate(self) + observers.forEach { $0.send() } + performEffects() + observers = [] } - func perform(effect: Effect) { - + func performEffects() { + + } + + private var observers: Set = [] + + func getValue(_ path: KeyPath>) -> Value { + let root = environment.get(Root.self) + let observableValue = root[keyPath: path] + return observableValue.value + } + + func set(value newValue: Value, path: KeyPath>) { + let root = environment.get(Root.self) + let observableValue = root[keyPath: path] + // We pop all observers of the observable values mutated by the decision. + // it also will prevent their observers to be notified + // until decision application is complete. + let valueObservers = observableValue.observation.popObservers() + // then we add them into set of all the observers that we will notify + // when all states affected by decision are mutated. + // this way we squash all the updates to: + // Each observer notified **once**, + // regardless how many values were updated. + // E.g. some object observes `A.a` `A.b` and `B.a` where A and B are roots. + // and .a .b are values. + // Decision updates all of them, but since it's a single observer (Observer.id), + // it will only get one update. + observers.formUnion(valueObservers) + observableValue.value = newValue } /** Subscript to direct read/write access to any atomic state. */ - public subscript(_ path: KeyPath>) -> Value { - get { - let root = environment.get(Root.self) - let observableValue = root[keyPath: path] - return observableValue.wrappedValue - } - set { - let root = environment.get(Root.self) - let observableValue = root[keyPath: path] - observableValue.set(value: newValue) - } + public subscript< + Root: StateRoot, + Value + >( + _ path: KeyPath> + ) -> Value { + get { getValue(path.appending(path: \.storage)) } + set { set(value: newValue, path: path.appending(path: \.storage)) } + } + + public subscript< + Root: StateRoot, + Wrapper: ObservableValueStorageWrapper, + Value + >( + path: KeyPath + ) -> Value where Wrapper.Value == Value { + get { getValue(path.appending(path: \.storage)) } + set { set(value: newValue, path: path.appending(path: \.storage)) } } /** Subscript to direct read/write access to any identified state. */ - public subscript( + public subscript< + Identifier: Hashable, + Root: IdentifiedStateRoot, + Value + >( _ path: KeyPath>, at id: Identifier ) -> Value where Root.Identifier == Identifier { @@ -93,7 +131,7 @@ public typealias EnvironmentMutation = (DecisionEnvironment) -> Void } set { let root = environment.get(Root.self, at: id) - let observableValue = root[keyPath: path] + let observableValue = root[keyPath: path.appending(path: \.storage)] observableValue.set(value: newValue) } } diff --git a/Decide/Environment/Observability.swift b/Decide/Environment/Observability.swift index 93ce19f..97e66eb 100644 --- a/Decide/Environment/Observability.swift +++ b/Decide/Environment/Observability.swift @@ -16,9 +16,14 @@ import Foundation /// Holds a week reference to actual observer, notifies only if object still exist. public final class Observer: Hashable { - private(set) var notify: () -> Void + private var notify: () -> Void private var id: ObjectIdentifier + public func send() { + print("notified \(id)") + notify() + } + @MainActor init(_ observer: O, notify: @escaping () -> Void) { self.notify = notify self.id = ObjectIdentifier(observer) @@ -51,7 +56,7 @@ public final class Observer: Hashable { func sendAll() { let observers = popObservers() - observers.forEach { $0.notify() } + observers.forEach { $0.send() } } } diff --git a/Decide/Macros.swift b/Decide/Macros.swift deleted file mode 100644 index 80df32a..0000000 --- a/Decide/Macros.swift +++ /dev/null @@ -1,15 +0,0 @@ -#if canImport(DecideMacros) -import DecideMacros - -@attached( - member, - names: named(environment), - named(init(environment:)) -) -@attached(memberAttribute) -@attached(extension, conformances: StateRoot) -public macro EnvironmentObservable() = #externalMacro( - module: "DecideMacros", - type: "EnvironmentObservableMacro" -) -#endif diff --git a/Decide/Persistency/Persistency.swift b/Decide/Persistency/Persistency.swift index f09c47a..97161bb 100644 --- a/Decide/Persistency/Persistency.swift +++ b/Decide/Persistency/Persistency.swift @@ -21,15 +21,16 @@ import Foundation */ @propertyWrapper @MainActor -public final class Persistent: ObservableValueWrapper { +public final class Persistent: ObservableValueStorageWrapper { public var wrappedValue: Value { storage.value } + public var projectedValue: Persistent { self } public var storage: ValueStorage public init(wrappedValue: @autoclosure @escaping () -> Value) { self.storage = ValueStorage(initialValue: wrappedValue) } - public init(wrappedValue: Wrapper) where Wrapper.Value == Value { + public init(wrappedValue: Wrapper) where Wrapper.Value == Value { self.storage = wrappedValue.storage } } diff --git a/Decide/RemoteValue/RemoteSync.swift b/Decide/RemoteValue/RemoteSync.swift index e60fba3..8937c03 100644 --- a/Decide/RemoteValue/RemoteSync.swift +++ b/Decide/RemoteValue/RemoteSync.swift @@ -22,15 +22,16 @@ import Foundation */ @propertyWrapper @MainActor -public final class RemoteValue: ObservableValueWrapper { +public final class RemoteValue: ObservableValueStorageWrapper { public var wrappedValue: Value { storage.value } + public var projectedValue: RemoteValue { self } public var storage: ValueStorage public init(wrappedValue: @autoclosure @escaping () -> Value) { self.storage = ValueStorage(initialValue: wrappedValue) } - public init(wrappedValue: Wrapper) where Wrapper.Value == Value { + public init(wrappedValue: Wrapper) where Wrapper.Value == Value { self.storage = wrappedValue.storage } } diff --git a/Decide/State/ObservableValue.swift b/Decide/State/ObservableValue.swift index c09f5cd..8635ce3 100644 --- a/Decide/State/ObservableValue.swift +++ b/Decide/State/ObservableValue.swift @@ -17,9 +17,10 @@ Contains the reference to the storage of the value. */ @MainActor -public protocol ObservableValueWrapper { +public protocol ObservableValueStorageWrapper { associatedtype Value var storage: ValueStorage { get } + var projectedValue: Self { get } } /** @@ -28,35 +29,20 @@ public protocol ObservableValueWrapper { */ @propertyWrapper @MainActor -public final class ObservableValue { - +public final class ObservableValue: ObservableValueStorageWrapper { public var wrappedValue: Value { - valueStorage.value + storage.value } public var projectedValue: ObservableValue { self } - var valueStorage: ValueStorage - var observation = ObserverStorage() + public var storage: ValueStorage public init(wrappedValue: @autoclosure @escaping () -> Value) { - self.valueStorage = ValueStorage(initialValue: wrappedValue) + self.storage = ValueStorage(initialValue: wrappedValue) } - public init(wrappedValue: Wrapper) where Wrapper.Value == Value { - self.valueStorage = wrappedValue.storage + public init(wrappedValue: Wrapper) where Wrapper.Value == Value { + self.storage = wrappedValue.storage } } - -extension ObservableValue { - public func getValueSubscribing(observer: Observer) -> Value { - observation.subscribe(observer) - return wrappedValue - } - - public func set(value newValue: Value) { - valueStorage.value = newValue - observation.sendAll() - } -} - diff --git a/Decide/State/ValueStorage.swift b/Decide/State/ValueStorage.swift index afee591..0b3d706 100644 --- a/Decide/State/ValueStorage.swift +++ b/Decide/State/ValueStorage.swift @@ -16,6 +16,7 @@ import Foundation @MainActor public final class ValueStorage { + var observation = ObserverStorage() public var initialValue: () -> Value public var value: Value { get { @@ -39,3 +40,15 @@ public final class ValueStorage { self.initialValue = initialValue } } + +extension ValueStorage { + public func getValueSubscribing(observer: Observer) -> Value { + observation.subscribe(observer) + return value + } + + public func set(value newValue: Value) { + value = newValue + observation.sendAll() + } +} diff --git a/DecideMacros-Tests/Decide_Tests.swift b/DecideMacros-Tests/Decide_Tests.swift deleted file mode 100644 index 19d5624..0000000 --- a/DecideMacros-Tests/Decide_Tests.swift +++ /dev/null @@ -1,14 +0,0 @@ -import XCTest -import Decide - -#if canImport(DecideMacros) -final class Decide_Tests: XCTestCase { - @EnvironmentObservable - final class Notes { - @Persistent - var name: String = "" - - var count: Int = 0 - } -} -#endif diff --git a/DecideMacros/EnvironmentObservable.swift b/DecideMacros/EnvironmentObservable.swift deleted file mode 100644 index 03014f4..0000000 --- a/DecideMacros/EnvironmentObservable.swift +++ /dev/null @@ -1,53 +0,0 @@ -import SwiftSyntax -import SwiftSyntaxMacros - -public struct EnvironmentObservableMacro: MemberMacro, MemberAttributeMacro { - public static func expansion( - of node: SwiftSyntax.AttributeSyntax, - attachedTo declaration: some SwiftSyntax.DeclGroupSyntax, - providingAttributesFor member: some SwiftSyntax.DeclSyntaxProtocol, - in context: some SwiftSyntaxMacros.MacroExpansionContext - ) throws -> [SwiftSyntax.AttributeSyntax] { - return [ - AttributeSyntax( - attributeName: IdentifierTypeSyntax( - name: .identifier("ObservableValue") - ) - ) - ] - } - - // MARK: - MemberMacro - public static func expansion( - of node: AttributeSyntax, - providingMembersOf declaration: some DeclGroupSyntax, - in context: some MacroExpansionContext - ) throws -> [DeclSyntax] { - guard let _ = declaration.asProtocol(NamedDeclSyntax.self) else { - return [] - } - - let environment: DeclSyntax = - """ - public unowned let environment: Decide.SharedEnvironment - public init(environment: Decide.SharedEnvironment) { - self.environment = environment - } - """ - - return [environment] - } -} - - -extension EnvironmentObservableMacro: ExtensionMacro { - public static func expansion( - of node: AttributeSyntax, - attachedTo declaration: some DeclGroupSyntax, - providingExtensionsOf type: some TypeSyntaxProtocol, - conformingTo protocols: [TypeSyntax], - in context: some MacroExpansionContext - ) throws -> [ExtensionDeclSyntax] { - [try ExtensionDeclSyntax("extension \(type): Decide.StateRoot {}")] - } -} diff --git a/DecideMacros/Plugin.swift b/DecideMacros/Plugin.swift deleted file mode 100644 index 9bd450c..0000000 --- a/DecideMacros/Plugin.swift +++ /dev/null @@ -1,11 +0,0 @@ -#if canImport(SwiftCompilerPlugin) -import SwiftCompilerPlugin -import SwiftSyntaxMacros - -@main -struct DecideCompilerPlugin: CompilerPlugin { - let providingMacros: [Macro.Type] = [ - EnvironmentObservableMacro.self, - ] -} -#endif diff --git a/IOWrappers/Atomic.swift b/IOWrappers/Atomic.swift deleted file mode 100644 index 3f68e1b..0000000 --- a/IOWrappers/Atomic.swift +++ /dev/null @@ -1,184 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Decide package open source project -// -// Copyright (c) 2020-2023 Maxim Bazarov and the Decide package -// open source project authors -// Licensed under MIT -// -// See LICENSE.txt for license information -// -// SPDX-License-Identifier: MIT -// -//===----------------------------------------------------------------------===// - -import Foundation - - -//===----------------------------------------------------------------------===// -// MARK: - SwiftUI View Environment -//===----------------------------------------------------------------------===// - -#if canImport(SwiftUI) -import SwiftUI - -/** Property wrapper that provides two-way access to the value - by ``ObservableState`` KeyPath on ``AtomicStorage``from the view environment. - */ -@propertyWrapper -@MainActor -public struct Observe: DynamicProperty { - - @SwiftUI.Environment(\.stateEnvironment) var environment - @ObservedObject var binding: ObservableState.Binding - - public init( - _ keyPath: KeyPath>, - file: StaticString = #fileID, - line: UInt = #line - ) { - self.binding = .init( - ref: ObservableState.Reference( - state: { $0.observableState(keyPath) }, - debugDescription: String(describing: keyPath) - ), - context: Context(file: file, line: line) - ) - } - - public var wrappedValue: Value { - get { binding.getValue(in: environment, observer: Observer(binding)) } - } -} - -/** - - - */ -@propertyWrapper -@MainActor public struct Bind: DynamicProperty { - - @SwiftUI.Environment(\.stateEnvironment) var environment - @ObservedObject var binding: ObservableState.Binding - - public init( - _ keyPath: KeyPath>, - file: StaticString = #fileID, - line: UInt = #line - ) { - self.binding = .init( - ref: ObservableState.Reference( - state: { $0.observableState(keyPath.appending(path: \.wrappedValue)) }, - debugDescription: String(describing: keyPath) - ), - context: Context(file: file, line: line) - ) - } - - public var wrappedValue: Value { - get { binding.getValue(in: environment, observer: Observer(binding)) } - nonmutating set { binding.setValue(in: environment, newValue: newValue) } - } - - public var projectedValue: Binding { - Binding( - get: { wrappedValue }, - set: { wrappedValue = $0 } - ) - } -} - -#endif - - -//===----------------------------------------------------------------------===// -// MARK: - Default Environment -//===----------------------------------------------------------------------===// - -@propertyWrapper -@MainActor public struct DefaultObserve { - @DefaultEnvironment var environment - var binding: ObservableState.Binding - - public init( - _ keyPath: KeyPath>, - file: StaticString = #fileID, - line: UInt = #line - ) { - self.binding = .init( - ref: ObservableState.Reference( - state: { $0.observableState(keyPath) }, - debugDescription: String(describing: keyPath) - ), - context: Context(file: file, line: line) - ) - } - - public static subscript( - _enclosingInstance instance: EnclosingObject, - wrapped wrappedKeyPath: KeyPath, - storage storageKeyPath: KeyPath - ) -> Value { - get { - let storage = instance[keyPath: storageKeyPath] - return storage.binding.getValue(in: storage.environment, observer: Observer(instance)) - } - set { - let storage = instance[keyPath: storageKeyPath] - return storage.binding.setValue(in: storage.environment, newValue: newValue) - } - } - - @available(*, unavailable, message: "@DefaultObserve can only be enclosed by EnvironmentObservingObject.") - public var wrappedValue: Value { - get { fatalError() } - nonmutating set { fatalError() } - } -} - - -/** - - - */ -@propertyWrapper -@MainActor public struct DefaultBind: DynamicProperty { - - @DefaultEnvironment var environment - @ObservedObject var binding: ObservableState.Binding - - public init( - _ keyPath: KeyPath>, - file: StaticString = #fileID, - line: UInt = #line - ) { - self.binding = .init( - ref: ObservableState.Reference( - state: { $0.observableState(keyPath.appending(path: \.wrappedValue)) }, - debugDescription: String(describing: keyPath) - ), - context: Context(file: file, line: line) - ) - } - - public static subscript( - _enclosingInstance instance: EnclosingObject, - wrapped wrappedKeyPath: KeyPath, - storage storageKeyPath: KeyPath - ) -> Value { - get { - let storage = instance[keyPath: storageKeyPath] - return storage.binding.getValue(in: storage.environment, observer: Observer(instance)) - } - set { - let storage = instance[keyPath: storageKeyPath] - return storage.binding.setValue(in: storage.environment, newValue: newValue) - } - } - - @available(*, unavailable, message: "@DefaultBind can only be enclosed by EnvironmentObservingObject.") - public var wrappedValue: Value { - get { fatalError() } - nonmutating set { fatalError() } - } -} diff --git a/IOWrappers/Identifiable.swift b/IOWrappers/Identifiable.swift deleted file mode 100644 index 5551278..0000000 --- a/IOWrappers/Identifiable.swift +++ /dev/null @@ -1,250 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Decide package open source project -// -// Copyright (c) 2020-2023 Maxim Bazarov and the Decide package -// open source project authors -// Licensed under MIT -// -// See LICENSE.txt for license information -// -// SPDX-License-Identifier: MIT -// -//===----------------------------------------------------------------------===// - -import Combine - -#if canImport(SwiftUI) -import SwiftUI - -@propertyWrapper -@MainActor public struct ObserveKeyed, Value>: DynamicProperty { - - @SwiftUI.Environment(\.stateEnvironment) var environment - @ObservedObject var binding: LazyBinding - - public init( - _ keyPath: KeyPath>, - file: StaticString = #fileID, - line: UInt = #line - ) { - self.binding = .init( - keyPath: keyPath, - context: Context(file: file, line: line) - ) - } - - public subscript(_ identifier: Identifier) -> Value { - get { binding.bound(id: identifier).getValue(in: environment, observer: Observer(binding)) } - } - - public var wrappedValue: Self { - self - } -} - - -@propertyWrapper -@MainActor public struct BindKeyed, Value>: DynamicProperty { - - @SwiftUI.Environment(\.stateEnvironment) var environment - @ObservedObject var binding: LazyBinding - - public init( - _ keyPath: KeyPath>, - file: StaticString = #fileID, - line: UInt = #line - ) { - self.binding = .init( - keyPath: keyPath.appending(path: \.wrappedValue), - context: Context(file: file, line: line) - ) - } - - public subscript(_ identifier: Identifier) -> Binding { - Binding( - get: { binding.bound(id: identifier).getValue(in: environment, observer: Observer(binding)) }, - set: { binding.bound(id: identifier).setValue(in: environment, newValue: $0) } - ) - } - - public subscript(_ identifier: Identifier) -> Value { - get { binding.bound(id: identifier).getValue(in: environment, observer: Observer(binding)) } - } - - public var wrappedValue: Self { - self - } -} -#endif - - -@propertyWrapper -@MainActor public struct DefaultObserveKeyed, Value> { - @DefaultEnvironment var environment - @ObservedObject var binding: LazyBinding - - @MainActor public final class StateForKey { - weak var enclosedInstance: EnvironmentObservingObject? - unowned var binding: LazyBinding - unowned var environment: ApplicationEnvironment - - init( - enclosedInstance: EnvironmentObservingObject?, - binding: LazyBinding, - environment: ApplicationEnvironment - ) { - self.enclosedInstance = enclosedInstance - self.binding = binding - self.environment = environment - } - - public subscript(_ identifier: Identifier) -> Value { - get { - var observer: Observer? - if let enclosedInstance { - observer = Observer(enclosedInstance) - } - return binding - .bound(id: identifier) - .getValue(in: environment, observer: observer) - } - } - } - - public init( - _ keyPath: KeyPath>, - file: StaticString = #fileID, - line: UInt = #line - ) { - self.binding = .init( - keyPath: keyPath, - context: Context(file: file, line: line) - ) - } - - public static subscript( - _enclosingInstance instance: EnclosingObject, - wrapped wrappedKeyPath: KeyPath, - storage storageKeyPath: KeyPath - ) -> StateForKey { - get { - let storage = instance[keyPath: storageKeyPath] - return StateForKey( - enclosedInstance: instance, - binding: storage.binding, - environment: storage.environment - ) - } - set {} - } - - @available(*, unavailable, message: "@DefaultObserveKeyed can only be enclosed by EnvironmentObservingObject.") - public var wrappedValue: StateForKey { - fatalError() - } -} - -@propertyWrapper -@MainActor public struct DefaultBindKeyed, Value> { - @DefaultEnvironment var environment - @ObservedObject var binding: LazyBinding - - public init( - _ keyPath: KeyPath>, - file: StaticString = #fileID, - line: UInt = #line - ) { - self.binding = .init( - keyPath: keyPath.appending(path: \.wrappedValue), - context: Context(file: file, line: line) - ) - } - - @MainActor public final class StateForKey { - weak var enclosedInstance: EnvironmentObservingObject? - unowned var binding: LazyBinding - unowned var environment: ApplicationEnvironment - - init( - enclosedInstance: EnvironmentObservingObject?, - binding: LazyBinding, - environment: ApplicationEnvironment - ) { - self.enclosedInstance = enclosedInstance - self.binding = binding - self.environment = environment - } - - public subscript(_ identifier: Identifier) -> Value { - get { - var observer: Observer? - if let enclosedInstance { - observer = Observer(enclosedInstance) - } - return binding - .bound(id: identifier) - .getValue(in: environment, observer: observer) - } - set { - binding - .bound(id: identifier) - .setValue(in: environment, newValue: newValue) - } - } - } - - public static subscript( - _enclosingInstance instance: EnclosingObject, - wrapped wrappedKeyPath: KeyPath, - storage storageKeyPath: KeyPath - ) -> StateForKey { - get { - let storage = instance[keyPath: storageKeyPath] - return StateForKey( - enclosedInstance: instance, - binding: storage.binding, - environment: storage.environment - ) - } - set {} - } - - - @available(*, unavailable, message: "@DefaultObserveKeyed can only be enclosed by EnvironmentObservingObject.") - public var wrappedValue: StateForKey { - fatalError() - } -} - - -/** - We need id to use a keyed state accessors e.g. `@ObserveKeyed(...)` - but we can't get it, since it's a static initializer we don't have - access to the instance hence none of its properties, - so user can't possibly have an id at this point. - - The idea here is to prepare everything and create a binding on the fly - once we have an id. - */ -@MainActor final class LazyBinding, Value>: ObservableObject { - let keyPath: KeyPath> - let context: Context - - init(keyPath: KeyPath>, context: Context) { - self.keyPath = keyPath - self.context = context - } - - func bound(id: Identifier) -> ObservableState.Binding { - let stateReference = ObservableState.Reference.init( - state: { environment in - environment.observableState(self.keyPath, at: id) - }, - debugDescription: "("+String(describing: keyPath) + " at: \(id))" - ) - - let binding = ObservableState.Binding.init(ref: stateReference, context: context) - return binding - } -} diff --git a/Package.swift b/Package.swift index bed76c8..8a769fe 100644 --- a/Package.swift +++ b/Package.swift @@ -27,48 +27,17 @@ let package = Package( products: [ .library(name: "Decide", targets: ["Decide"]), ], - dependencies: [ - .package(url: "https://github.com/apple/swift-syntax.git", "508.0.0"..<"510.0.0"), - ], targets: [ .target( name: "Decide", - dependencies: [ - "DecideMacros" - ], path: "Decide" ), - .macro( - name: "DecideMacros", - dependencies: [ - .product(name: "SwiftSyntaxMacros", package: "swift-syntax"), - .product(name: "SwiftCompilerPlugin", package: "swift-syntax") - ], - path: "DecideMacros" - ), .testTarget( name: "Decide-Tests", dependencies: [ - "Decide", - "DecideTesting" + "Decide" ], path: "Decide-Tests" ), - // - Decide Testing - - .target( - name: "DecideTesting", - dependencies: ["Decide"], - path: "DecideTesting" - ), - // Macros Tests - .testTarget( - name: "DecideMacros-Tests", - dependencies: [ - "Decide", - "DecideMacros", - .product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax"), - ], - path: "DecideMacros-Tests" - ), ] )