diff --git a/Package.swift b/Package.swift
index 60624ba2ca..dd0a3c28ea 100644
--- a/Package.swift
+++ b/Package.swift
@@ -45,10 +45,12 @@ let package = Package(
.target(name: "VergeMacros", dependencies: ["VergeMacrosPlugin"]),
.target(name: "VergeTiny", dependencies: []),
+ .target(name: "VergeComparator"),
.target(
name: "Verge",
dependencies: [
"VergeMacros",
+ "VergeComparator",
.product(name: "Atomics", package: "swift-atomics"),
.product(name: "DequeModule", package: "swift-collections"),
.product(name: "ConcurrencyTaskManager", package: "swift-concurrency-task-manager"),
@@ -64,6 +66,7 @@ let package = Package(
name: "VergeNormalization",
dependencies: [
"VergeMacros",
+ "VergeComparator",
.product(name: "HashTreeCollections", package: "swift-collections"),
]
),
diff --git a/Sources/Verge/Verge.swift b/Sources/Verge/Verge.swift
index 975e1ffe0c..0c70f8cc2c 100644
--- a/Sources/Verge/Verge.swift
+++ b/Sources/Verge/Verge.swift
@@ -1,3 +1,4 @@
@_exported import ConcurrencyTaskManager
@_exported import Combine
+@_exported import VergeComparator
diff --git a/Sources/Verge/Store/Comparer.swift b/Sources/VergeComparator/Comparator.swift
similarity index 99%
rename from Sources/Verge/Store/Comparer.swift
rename to Sources/VergeComparator/Comparator.swift
index 57903fe9a2..e351a0a783 100644
--- a/Sources/Verge/Store/Comparer.swift
+++ b/Sources/VergeComparator/Comparator.swift
@@ -22,6 +22,7 @@
import Foundation
import os.log
+// TODO: will rename as Comparator
public protocol Comparison: Sendable {
associatedtype Input
diff --git a/Sources/VergeMacrosPlugin/DatabaseMacro.swift b/Sources/VergeMacrosPlugin/DatabaseMacro.swift
index a7cb8f3a9e..f2348ebbae 100644
--- a/Sources/VergeMacrosPlugin/DatabaseMacro.swift
+++ b/Sources/VergeMacrosPlugin/DatabaseMacro.swift
@@ -216,6 +216,13 @@ public struct DatabaseTableMacro: Macro {
}
+extension DatabaseTableMacro: PeerMacro {
+ public static func expansion(of node: SwiftSyntax.AttributeSyntax, providingPeersOf declaration: some SwiftSyntax.DeclSyntaxProtocol, in context: some SwiftSyntaxMacros.MacroExpansionContext) throws -> [SwiftSyntax.DeclSyntax] {
+ return []
+ }
+
+}
+
extension DatabaseTableMacro: AccessorMacro {
public static func expansion(
of node: SwiftSyntax.AttributeSyntax,
@@ -230,16 +237,16 @@ extension DatabaseTableMacro: AccessorMacro {
let id = identifier(from: declaration.cast(VariableDeclSyntax.self))
return [
- """
- get {
- _$\(id)
- }
- """,
- """
- set {
- _$\(id) = newValue
- }
- """ ,
+// """
+// get {
+// _$\(id)
+// }
+// """,
+// """
+// set {
+// _$\(id) = newValue
+// }
+// """ ,
]
}
diff --git a/Sources/VergeNormalization/Comparison.swift b/Sources/VergeNormalization/Comparison.swift
new file mode 100644
index 0000000000..81708d8a65
--- /dev/null
+++ b/Sources/VergeNormalization/Comparison.swift
@@ -0,0 +1,62 @@
+import VergeComparator
+
+public enum NormalizedStorageComparisons {
+
+ /// True indicates database is not changed
+ public struct StorageComparison: Comparison {
+ public typealias Input = Storage
+
+ public func callAsFunction(_ lhs: Storage, _ rhs: Storage) -> Bool {
+
+ lhs == rhs
+
+// (lhs._backingStorage.entityUpdatedMarker, lhs._backingStorage.indexUpdatedMarker) == (rhs._backingStorage.entityUpdatedMarker, rhs._backingStorage.indexUpdatedMarker)
+ }
+ }
+
+ /// Returns true if the table of the entity in database has no changes.
+ ///
+ /// - Complexity: O(1)
+ public struct TableComparison: Comparison {
+
+ public typealias Input = Storage
+
+ public func callAsFunction(_ lhs: Storage, _ rhs: Storage) -> Bool {
+// lhs._backingStorage.entityBackingStorage.table(Entity.self).updatedMarker == rhs._backingStorage.entityBackingStorage.table(Entity.self).updatedMarker
+ fatalError()
+ }
+
+ }
+
+ /// Returns true if the updates result does not contain the entity.
+ public struct UpdateComparison: Comparison {
+
+ public typealias Input = Storage
+
+
+ public let entityID: Entity.EntityID
+
+ public init(entityID: Entity.EntityID) {
+ self.entityID = entityID
+ }
+
+ public func callAsFunction(_ lhs: Storage, _ rhs: Storage) -> Bool {
+
+ fatalError()
+
+// guard let result = rhs._backingStorage.lastUpdatesResult else {
+// return false
+// }
+// guard !result.wasUpdated(entityID) else {
+// return false
+// }
+// guard !result.wasDeleted(entityID) else {
+// return false
+// }
+// return true
+
+ }
+ }
+
+}
+
diff --git a/Sources/VergeNormalization/NormalizedStorageType.swift b/Sources/VergeNormalization/NormalizedStorageType.swift
index 491d85f30c..86b591bd59 100644
--- a/Sources/VergeNormalization/NormalizedStorageType.swift
+++ b/Sources/VergeNormalization/NormalizedStorageType.swift
@@ -1,5 +1,5 @@
-public protocol NormalizedStorageType {
+public protocol NormalizedStorageType: Equatable {
func finalizeTransaction(transaction: inout ModifyingTransaction)
diff --git a/Sources/VergeNormalization/VergeNormalization+Macros.swift b/Sources/VergeNormalization/VergeNormalization+Macros.swift
index 859b624450..735744ec10 100644
--- a/Sources/VergeNormalization/VergeNormalization+Macros.swift
+++ b/Sources/VergeNormalization/VergeNormalization+Macros.swift
@@ -1,10 +1,10 @@
-@attached(member, names: arbitrary)
+//@attached(member, names: arbitrary)
//@attached(memberAttribute)
@attached(extension, conformances: NormalizedStorageType, Equatable, names: named(Context), named(BBB), arbitrary)
public macro NormalizedStorage() = #externalMacro(module: "VergeMacrosPlugin", type: "DatabaseMacro")
-@attached(accessor)
+@attached(peer)
public macro TableAccessor() = #externalMacro(module: "VergeMacrosPlugin", type: "DatabaseTableMacro")
@@ -25,7 +25,7 @@ struct MyDatabase {
private func play() {
- var db = MyDatabase.init()
+ var db = MyDatabase.init(user: .init())
db.performBatchUpdates { t in
t.modifying.user.insert(.init())
diff --git a/Sources/VergeNormalizationDerived/DispatcherType+.swift b/Sources/VergeNormalizationDerived/DispatcherType+.swift
index 47796b87f2..8481fe0112 100644
--- a/Sources/VergeNormalizationDerived/DispatcherType+.swift
+++ b/Sources/VergeNormalizationDerived/DispatcherType+.swift
@@ -4,17 +4,49 @@ extension DispatcherType {
_StorageSelector: StorageSelector,
_TableSelector: TableSelector
>(
- selector: consuming AbsoluteTableSelector<_StorageSelector, _TableSelector>
+ selector: consuming AbsoluteTableSelector<_StorageSelector, _TableSelector>,
+ entityID: _TableSelector.Entity.EntityID
) -> Derived>
where
_StorageSelector.Storage == _TableSelector.Storage,
_StorageSelector.Source == Changes
{
- derived(SingleEntityPipeline(selector: selector), queue: .passthrough)
+ // TODO: caching
+
+ return derived(
+ SingleEntityPipeline(
+ targetIdentifier: entityID,
+ selector: selector
+ ),
+ queue: .passthrough
+ )
}
+ public func derivedEntity2<
+ _StorageSelector: StorageSelector,
+ _TableSelector: TableSelector
+ >(
+ selector: consuming AbsoluteTableSelector<_StorageSelector, _TableSelector>,
+ entityID: _TableSelector.Entity.EntityID
+ ) -> Derived>
+ where
+ _StorageSelector.Storage == _TableSelector.Storage,
+ _StorageSelector.Source == Changes
+ {
+
+ // TODO: caching
+
+ return derived(
+ SingleEntityPipeline(
+ targetIdentifier: entityID,
+ selector: selector
+ ),
+ queue: .passthrough
+ )
+
+ }
}
private struct SingleEntityPipeline<
@@ -48,6 +80,11 @@ where _StorageSelector.Storage == _TableSelector.Storage, _StorageSelector.Sourc
}
func yieldContinuously(_ input: Input) -> Verge.ContinuousResult> {
+
+ guard let previous = input.previous else {
+ return .new(yield(input))
+ }
+
fatalError()
}