cashay
cashay copied to clipboard
remove id from the @cached directive
the id, ids fields are pretty useless & can use a pre-cached value causing source.id to come up undefined. It's not terrible, but it causes an extra render. Plus this makes for a smaller, more opinionated API.
I saw these changes reflected in the latest Action PR. Could you help illustrate how this works without id? I must admit, I've been a little foggy on the role of resolveCached.
Let's use an example:
const projectCardSubQuery = `
query {
project @cached(type: "Project") {
content
id
status
teamMemberId
updatedAt
teamMember @cached(type: "TeamMember") {
id
picture
preferredName
}
team @cached(type: "Team") {
id
name
}
}
}
`;
const mapStateToProps = (state, props) => {
const userId = state.auth.obj.sub;
const [teamId] = props.project.id.split('::');
const projectId = props.project.id;
const {project} = cashay.query(projectCardSubQuery, {
op: 'projectCardContainer',
key: projectId,
variables: {projectId},
resolveCached: {
project: () => projectId,
team: (source) => (doc) => source.id.startsWith(doc.id),
// example of returning a string instead of a function so it runs in O(1)
teamMember: (source) => source.teamMemberId
},
}).data;
So resolveCached for project returns a single parametric projectId; teamMember returns the id from the source document; and team returns a function that returns a bool.
How does this work? does the resolveCached project function work by indexing into the normalized collection of Projects? Then the source parameter passed to the resolvedCached teamMember function is a Project? And then Team is found (O(n)) by ensuring that the Project id starts with the Team Id?
Is that right?
Yep! I could probably elucidate this a little better in the docs, but basically each method in resolveCached is a function that can return a string, an array of strings, or a function.
If it returns a string, in this case projectId, it with return store.getState().cashay.entities[type='Project'][projectId].
Next, look at the teamMember method. It also returns a string source.teamMemberId. The source is the parent object (just like in a GraphQL resolve function).
So in this case:
const id = `store.getState().cashay.entities[type='Project'][projectId].teamMemberId`
return store.getState().cashay.entities[type='TeamMember'][id]
Finally, just like you said, the team method returns a function, which will run in O(n) over every single Team entity. It returns a single value. For an array of values, the type would be type: [Team].
They way you just wrote about it here is super, super clear. This would be great for the docs!