Feature request: export RelayOptimisticRecordSource to make it extensible
- Dominant language
- Rust
- Stars
- 19k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
# Problem
It is possible to extend and provide your own record source:
```ts
import { Environment, Store, RecordSource } from 'relay-runtime'
class MyRecordSource extends RecordSource {
// ...
}
export const RelayEnvironment = new Environment({
// ...
store: new Store(new MyRecordSource())})
})
```
However, it is not currently possible to easily extend or provide the [RelayOptimisticRecordSource](https://github.com/facebook/relay/blob/main/packages/relay-runtime/store/RelayOptimisticRecordSource.js#L34) to the store.
# Question
Is there a reason to keep the RelayOptimisticRecordSource internal?
# Discussion
Would it be possible to:
1. Export [RelayOptimisticRecordSource](https://github.com/facebook/relay/blob/main/packages/relay-runtime/store/RelayOptimisticRecordSource.js#L34) to make it extensible? Currently, developers have to define it from scratch and use it in a custom [Store.snapshot](https://github.com/facebook/relay/blob/main/packages/relay-runtime/store/RelayModernStore.js#L543-L545) just to make the smallest modification.
2. Accept OptimisticRecordSource in the store constructor to automatically pick the custom implementation, without having to extend the Store as in point 1.
# PRs
If this proposal is accepted, I could submit a PR for discussion point 1 (just exporting the RelayOptimisticRecordSource with a one-line change) or a PR for both discussion points.
## Motivation
To link child nodes inside connections to their parent nodes, we have to ask the server for the relationship.
```graphql
fragment myNodeSomeConnection on myNode
id: parentID # same as inside every child!
someConnection {
edges {
node {
id
parent {
id: parentID # ask for parent to set linked relationship in the relay store
}
}
}
}
}
```
To avoid repeatedly asking for the same relationship, I use my own RecordSource to link records that didn't come linked from the server. For example:
```graphql
fragment myNodeSomeConnection on myNode
...theParent
someConnection {
edges {
node {
id
theParentId # I know that this child node is linked to the parent node, by asking the parent ID, instead of the parent relationship
}
}
}
}
```
then, in my record source:
```ts
class MyRecordSource extends RecordSource {
// ...
set(dataID: DataID, record: RelayRecord): void {
this._records.set(dataID, handleRecords(record))
}
}
function handleRecords(record: RelayRecord) => {
// ... link node to parent node before writing to the store...
return record
}
```
However, I have to perform the same computation inside the RelayOptimisticRecordSource.
```ts
class MyOptimisticRecordSource implements MutableRecordSource { // <-- can't extend RelayOptimisticRecordSource because it's not exported
// ...
set(dataID: DataID, record: Record): void {
this._sink.set(dataID, handleRecords(record))
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.