diff --git a/Sources/Sharing/SharedKeys/InMemoryKey.swift b/Sources/Sharing/SharedKeys/InMemoryKey.swift index c8c2494..af02b18 100644 --- a/Sources/Sharing/SharedKeys/InMemoryKey.swift +++ b/Sources/Sharing/SharedKeys/InMemoryKey.swift @@ -30,8 +30,8 @@ extension SharedReaderKey { /// /// See ``SharedReaderKey/inMemory(_:)`` to create values of this type. public struct InMemoryKey: SharedKey { - private let key: String private let store: InMemoryStorage + fileprivate let key: String fileprivate init(_ key: String) { @Dependency(\.defaultInMemoryStorage) var defaultInMemoryStorage self.key = key @@ -80,6 +80,15 @@ public struct InMemoryStorage: Hashable, Sendable { public func hash(into hasher: inout Hasher) { hasher.combine(id) } +// public func removeValue(for key: String) { +// removeValue(for: ) +// } + public func removeValue(for key: InMemoryKey, default defaultValue: Value) { + values.removeValue(for: key, default: defaultValue) + } + public func removeValue(for key: InMemoryKey.Default) { + removeValue(for: key.base, default: key.initialValue) + } fileprivate final class Values: Sendable { let storage = Mutex<[String: any Sendable]>([:]) @@ -99,6 +108,18 @@ public struct InMemoryStorage: Hashable, Sendable { } } } + + func removeValue(for key: InMemoryKey, default defaultValue: Value) { + @Dependency(PersistentReferences.self) var persistentReferences + let reference = persistentReferences.value( + forKey: .inMemory(key.key), + default: defaultValue, + skipInitialLoad: false + ) + reference.withLock { value in + value = defaultValue + } + } } } diff --git a/Tests/SharingTests/InMemoryTests.swift b/Tests/SharingTests/InMemoryTests.swift index 808dc9f..e04e691 100644 --- a/Tests/SharingTests/InMemoryTests.swift +++ b/Tests/SharingTests/InMemoryTests.swift @@ -22,6 +22,30 @@ import Testing #expect(count == 2) } + @Test func removeValue() async { + @Dependency(\.defaultInMemoryStorage) var storage + + do { + @Shared(.inMemory("count")) var count = 0 + + #expect(count == 0) + + $count.withLock { $0 += 1 } + + #expect(count == 1) + } + + do { + @Shared(.inMemory("count")) var count = 0 + + #expect(count == 1) + + storage.removeValue(for: InMemoryKey.inMemory("count"), default: 0) + + #expect(count == 0) + } + } + @Test func referenceCounting() async throws { do { @Shared(.inMemory("count")) var count = 0 diff --git a/Tests/SharingTests/ObservationTests.swift b/Tests/SharingTests/ObservationTests.swift index 9b518be..7857821 100644 --- a/Tests/SharingTests/ObservationTests.swift +++ b/Tests/SharingTests/ObservationTests.swift @@ -1,3 +1,4 @@ +import Dependencies import PerceptionCore import Sharing import Testing @@ -29,4 +30,30 @@ import Testing $count.withLock { $0 += 1 } } } + + @Test func removeValueShared() async { + @Dependency(\.defaultInMemoryStorage) var storage + @Shared(.inMemory("count")) var count = 0 + await confirmation { confirm in + withPerceptionTracking { + _ = count + } onChange: { + confirm() + } + storage.removeValue(for: InMemoryKey.inMemory("count"), default: 0) + } + } + + @Test func removeValueSharedReader() async { + @Dependency(\.defaultInMemoryStorage) var storage + @SharedReader(.inMemory("count")) var count = 0 + await confirmation { confirm in + withPerceptionTracking { + _ = count + } onChange: { + confirm() + } + storage.removeValue(for: InMemoryKey.inMemory("count"), default: 0) + } + } }