-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Core Data: Fix early return check for the record field-level resolutions #71541
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
Changes from all commits
5004b0d
d8c6aea
1c4d439
1294c4a
31cdbbb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -420,6 +420,62 @@ getEntityRecord.__unstableNormalizeArgs = ( | |
| return newArgs; | ||
| }; | ||
|
|
||
| /** | ||
| * Returns true if a record has been received for the given set of parameters, or false otherwise. | ||
| * | ||
| * Note: This action does not trigger a request for the entity record from the API | ||
| * if it's not available in the local state. | ||
| * | ||
| * @param state State tree | ||
| * @param kind Entity kind. | ||
| * @param name Entity name. | ||
| * @param key Record's key. | ||
| * @param query Optional query. | ||
| * | ||
| * @return Whether an entity record has been received. | ||
| */ | ||
| export function hasEntityRecord( | ||
| state: State, | ||
| kind: string, | ||
| name: string, | ||
| key?: EntityRecordKey, | ||
| query?: GetRecordsHttpQuery | ||
| ): boolean { | ||
| const queriedState = | ||
| state.entities.records?.[ kind ]?.[ name ]?.queriedData; | ||
| if ( ! queriedState ) { | ||
| return false; | ||
| } | ||
| const context = query?.context ?? 'default'; | ||
|
|
||
| // If expecting a complete item, validate that completeness. | ||
| if ( ! query || ! query._fields ) { | ||
| return !! queriedState.itemIsComplete[ context ]?.[ key ]; | ||
| } | ||
|
|
||
| const item = queriedState.items[ context ]?.[ key ]; | ||
| if ( ! item ) { | ||
| return false; | ||
| } | ||
|
|
||
| // When `query._fields` is provided, check that each requested field exists, | ||
| // including any nested paths, on the item; return false if any part is missing. | ||
| const fields = getNormalizedCommaSeparable( query._fields ) ?? []; | ||
| for ( let i = 0; i < fields.length; i++ ) { | ||
| const path = fields[ i ].split( '.' ); | ||
| let value = item; | ||
| for ( let p = 0; p < path.length; p++ ) { | ||
| const part = path[ p ]; | ||
| if ( ! value || ! Object.hasOwn( value, part ) ) { | ||
| return false; | ||
| } | ||
| value = value[ part ]; | ||
| } | ||
| } | ||
|
Comment on lines
+464
to
+474
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a micro-optimization, I was curious if Benchmarking codeimport Benchmark from "benchmark";
const fields = ["a", "b.c", "d"];
const item = { a: 1, b: { c: 2 }, e: 3 };
const suite = new Benchmark.Suite();
suite.add("before", () => {
for (let i = 0; i < fields.length; i++) {
const path = fields[i].split(".");
let value = item;
for (let p = 0; p < path.length; p++) {
const part = path[p];
if (!value || !Object.hasOwn(value, part)) {
return false;
}
value = value[part];
}
}
});
suite.add("after", () => {
for (const field of fields) {
const path = field.split(".");
let value = item;
for (const part of path) {
if (!value || !Object.hasOwn(value, part)) {
return false;
}
value = value[part];
}
}
});
suite.on("cycle", (event) => {
console.log(String(event.target));
});
suite.run({ async: true });
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for checking. That's also my experience that simple for loops perform better for now. |
||
|
|
||
| return true; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the Entity's record object by key. Doesn't trigger a resolver nor requests the entity records from the API if the entity record isn't available in the local state. | ||
| * | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking out loud: if we are checking for an item with specific fields and they are all cached, is it relevant that the context is not the same if we have the data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The data is stored by context, so looking it up by context is important. When there's no data for the same context, we'll have to make a request.