Skip to content

Surface persistence strategy of a Shared property #2982

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from

Conversation

stephencelis
Copy link
Member

This branch introduces a second generic to Shared that tracks the underlying persistence strategy:

Shared<Value, Persistence>

This means that a particular persistence strategy can expose endpoints that the Shared could statically call. For example, a remotely-backed Shared could expose a refresh endpoint for fetching the latest data:

@Shared(.api(.config)) var config = Config()

// ...

$config.persistence.refresh()

Now this change comes with some complications and source incompatibilities with earlier periods in the beta. In particular, Shared properties that are not backed by a persistence key can no longer be specified simply:

@Shared var count: Int

Due to limitations in Swift (lack of default generics, for example), the new generic cannot be inferred in this situation. The type used to describe the persistence strategy of such a shared value is Any, and so there is a type alias to simplify:

// Instead of:
@Shared<Int, Any> var count: Int

// Do:
@AnyShared var count: Int

In the future, if Swift ever does get default generics, we could maybe get rid of these type aliases.

We'd love it if folks could take this change for a spin and/or provide feedback. We're trying to strike the right balance for shared state in terms of features and power without sacrificing too much in the way of usability and API surface area.

This branch introduces a second generic to `Shared` that tracks the
underlying persistence strategy:

```swift
Shared<Value, Persistence>
```

This means that a particular persistence strategy can expose endpoints
that the `Shared` could statically call. For example, a remotely-backed
`Shared` could expose a `refresh` endpoint for fetching the latest data:

```swift
@shared(.api(.config)) var config = Config()

// ...

$config.persistence.refresh()
```

Now this change comes with some complications and source
incompatibilities with earlier periods in the beta. In particular,
`Shared` properties that are _not_ backed by a persistence key can no
longer be specified simply:

```swift
@shared var count: Int
```

Due to limitations in Swift (lack of default generics, for example), the
new generic cannot be inferred in this situation. The type used to
describe the persistence strategy of such a shared value is `Any`, and
so there is a type alias to simplify:

```swift
// Instead of:
@shared<Int, Any> var count: Int

// Do:
@AnyShared var count: Int
```

In the future, if Swift ever does get default generics, we could maybe
get rid of these type aliases.

We'd love it if folks could take this change for a spin and/or provide
feedback. We're trying to strike the right balance for shared state in
terms of features and power without sacrificing too much in the way of
usability and API surface area.
@stephencelis stephencelis added the shared state beta Related to our shared state release. label Apr 11, 2024
@stephencelis stephencelis requested a review from mbrandonw April 11, 2024 20:19
@stephencelis
Copy link
Member Author

Going to close this for now. We can revisit in the future if we find more motivating examples, but for now it is possible to write a custom property wrapper that wraps a Shared and exposes endpoints, instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
shared state beta Related to our shared state release.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants