Replies: 1 comment
-
|
+1 for this idea of read-only persistent external state. I haven't had a chance to play with the shared state beta yet, but this is exactly the use case (emulating SwiftData While, it is not entirely true that the Reducers don't modify the underlying state. I certainly do make changes to the underlying persistent data in some of my Reducers. However, I don't try to mutate the So instead, the underlying datastore is modified through its own dependency, and the |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm happy to say that so far I have had a smooth transition to
@Sharedin one of my projects. It cleaned up a very complex solution I had before to achieve the same functionality with a custom persistence client and custom reducer operator for synchronizing the data. However, during this process, I and some others have seemingly noted a particular kind of shared state that is read-only. After some brainstorming, I think it would be best if the library could provide better tooling for representing this kind of shared state.In particular, I have noticed 2 kinds of shared state:
@Queryin swift-data, GRDB value observations, the current user's location, etc.I think number 1 tends to be the more common case, but number 2 in my opinion is far more interesting since I believe the current shared state tools would add some unnecessary overhead in implementing it. Therefore, I want to focus most of this on number 2, but what I have in mind should work for both cases.
So utilizing the current tools for number 2, assuming that we have some kind of
PersistenceKeyconformance that behaves like@Queryin swift-data, and that we have some conversion process from@Modelto value types. Then the following would be quite non-sensical:This case would mirror why
@Queryis read-only in swift data. In this case, the reducer, or rather any reducer for that matter, has no business mutating the array of events since it could add an invalid event that wouldn't represent the query in@Shared.For the point on mutations, since
@Sharedalready allows mutations to its value, so we'll need a new property wrapper that prevents mutations to its value. A good name for this would be@Externalsince it would represent a value that's strictly external to the reducer.@Externalwould have a similar overload as@SharedwithPersistenceKey, so that should cover the first case of shared state that I mentioned where a small handful of reducers can mutate the state whilst others can only read the state.However, on the topic of
PersistenceKeys, the hypothetical@Query-like persistence key entirely controls the state of the query.PersistenceKeyhas some protocol requirements that introduce unnecessary overhead in implementing these kinds of read-only persistence keys, mainly due to the save method and the optionalValueassociated type. A new protocol for read-only persistence keys would be ideal, something like:The main thing here besides the lack of a save method, is unlike
PersistenceKeyloadandupdatesdon't deal with an optionalValue. This is because in theory there should be a sensible default that is entirely controlled by the external system, like an empty array of events if none could be found from the query in the earlier example.Using this protocol, there could then be an overload init of
@Externalthat allows for the usage ofExternalKeylike:Then, this would change the query example from before to:
Overall, I'm enjoying using
@Shared, and I see a lot of parallels with the shared state tools, anduseSyncExternalStorefrom the react world. As such I modeled theExternalKeyprotocol similarly to the function parameters ofuseSyncExternalStore.Beta Was this translation helpful? Give feedback.
All reactions