Skip to content

Commit

Permalink
combine ClientFieldVariant::RefetchField and ClientFieldVariant::Impe…
Browse files Browse the repository at this point in the history
…rativelyLoadedField
  • Loading branch information
rbalicki2 committed May 11, 2024
1 parent 08b0b80 commit f7b3e74
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 158 deletions.
70 changes: 28 additions & 42 deletions crates/graphql_artifact_generation/src/generate_artifacts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,19 +139,6 @@ fn get_artifact_infos<'schema>(
*component_name_and_path,
))
}
ClientFieldVariant::RefetchField(variant) => {
let function_import_statement = match &variant.primary_field_info {
Some(info) => generate_function_import_statement_for_mutation_reader(
&info.primary_field_field_map,
),
None => generate_function_import_statement_for_refetch_reader(),
};
ArtifactInfo::RefetchReader(generate_mutation_reader_artifact(
schema,
encountered_client_field,
function_import_statement,
))
}
ClientFieldVariant::ImperativelyLoadedField(variant) => {
let function_import_statement = match &variant.primary_field_info {
Some(info) => generate_function_import_statement_for_mutation_reader(
Expand Down Expand Up @@ -1142,38 +1129,36 @@ fn generate_reader_ast_node(

// This is indicative of poor data modeling.
match client_field.variant {
ClientFieldVariant::RefetchField(_) => {
let refetch_query_index = find_imperatively_fetchable_query_index(
root_refetched_paths,
path,
(*REFETCH_FIELD_NAME).into(),
)
.0;
format!(
"{indent_1}{{\n\
{indent_2}kind: \"RefetchField\",\n\
{indent_2}alias: \"{alias}\",\n\
{indent_2}readerArtifact: {client_field_string},\n\
{indent_2}refetchQuery: {refetch_query_index},\n\
{indent_1}}},\n",
)
}
ClientFieldVariant::ImperativelyLoadedField(ref s) => {
let refetch_query_index = find_imperatively_fetchable_query_index(
root_refetched_paths,
path,
s.client_field_scalar_selection_name.into(),
)
.0;
format!(
"{indent_1}{{\n\
{indent_2}kind: \"MutationField\",\n\
{indent_2}alias: \"{alias}\",\n\
{indent_2}// @ts-ignore\n\
{indent_2}readerArtifact: {client_field_string},\n\
{indent_2}refetchQuery: {refetch_query_index},\n\
{indent_1}}},\n",
)
match s.primary_field_info {
Some(_) => {
format!(
"{indent_1}{{\n\
{indent_2}kind: \"MutationField\",\n\
{indent_2}alias: \"{alias}\",\n\
{indent_2}// @ts-ignore\n\
{indent_2}readerArtifact: {client_field_string},\n\
{indent_2}refetchQuery: {refetch_query_index},\n\
{indent_1}}},\n",
)
}
None => {
format!(
"{indent_1}{{\n\
{indent_2}kind: \"RefetchField\",\n\
{indent_2}alias: \"{alias}\",\n\
{indent_2}readerArtifact: {client_field_string},\n\
{indent_2}refetchQuery: {refetch_query_index},\n\
{indent_1}}},\n",
)
}
}
}
_ => {
format!(
Expand Down Expand Up @@ -1311,10 +1296,11 @@ fn generate_output_type(client_field: &ValidatedClientField) -> ClientFieldOutpu
ClientFieldVariant::Eager(_) => {
ClientFieldOutputType("ReturnType<typeof resolver>".to_string())
}
ClientFieldVariant::RefetchField(_) => ClientFieldOutputType("() => void".to_string()),
ClientFieldVariant::ImperativelyLoadedField(_) => {
// TODO type these parameters
ClientFieldOutputType("(params: any) => void".to_string())
ClientFieldVariant::ImperativelyLoadedField(params) => {
match params.primary_field_info {
Some(_) => ClientFieldOutputType("(params: any) => void".to_string()),
None => ClientFieldOutputType("() => void".to_string()),
}
}
},
}
Expand Down
16 changes: 9 additions & 7 deletions crates/isograph_cli/src/refetch_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,17 @@ fn add_refetch_field_to_object(
name: (*REFETCH_FIELD_NAME).into(),
id: next_client_field_id,
selection_set_and_unwraps: Some((vec![id_field_selection], vec![])),
variant: ClientFieldVariant::RefetchField(ImperativelyLoadedFieldVariant {
client_field_scalar_selection_name: *REFETCH_FIELD_NAME,
top_level_schema_field_name: *NODE_FIELD_NAME,
top_level_schema_field_arguments: id_arguments,
variant: ClientFieldVariant::ImperativelyLoadedField(
ImperativelyLoadedFieldVariant {
client_field_scalar_selection_name: *REFETCH_FIELD_NAME,
top_level_schema_field_name: *NODE_FIELD_NAME,
top_level_schema_field_arguments: id_arguments,

primary_field_info: None,
primary_field_info: None,

root_object_id: query_id,
}),
root_object_id: query_id,
},
),
variable_definitions: vec![],
type_and_field: ObjectTypeAndFieldNames {
type_name: object.name,
Expand Down
130 changes: 25 additions & 105 deletions crates/isograph_schema/src/create_merged_selection_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use common_lang_types::{
ScalarFieldAlias, ScalarFieldName, SelectableFieldName, Span, VariableName, WithLocation,
WithSpan,
};
use graphql_lang_types::{GraphQLTypeAnnotation, NamedTypeAnnotation, NonNullTypeAnnotation};
use intern::{string_key::Intern, Lookup};
use isograph_lang_types::{
ClientFieldId, NonConstantValue, RefetchQueryIndex, SelectableServerFieldId, Selection,
Expand Down Expand Up @@ -245,7 +244,7 @@ pub fn create_merged_selection_set(
entrypoint: &ValidatedClientField,
) -> (MergedSelectionSet, Vec<RootRefetchedPath>) {
let mut merge_traversal_state = MergeTraversalState::new(encountered_client_field_ids);
let merged_selection_set = create_merged_selection_set_with_merge_traversal_state(
let full_merged_selection_set = create_merged_selection_set_with_merge_traversal_state(
schema,
parent_type,
validated_selections,
Expand All @@ -264,80 +263,9 @@ pub fn create_merged_selection_set(
(path_to_refetch_field, refetch_field_parent_id, client_field_variant),
)| {
let nested_merged_selection_set =
find_by_path(&merged_selection_set, &path_to_refetch_field);
find_by_path(&full_merged_selection_set, &path_to_refetch_field);

let (field_name, reachable_variables) = match client_field_variant {
ClientFieldVariant::RefetchField(_) => {
let type_to_refine_to = schema
.server_field_data
.object(refetch_field_parent_id)
.name;

let id_arguments = vec![WithLocation::new(
SelectionFieldArgument {
name: WithSpan::new(
"id".intern().into(),
Span::todo_generated(),
),
value: WithSpan::new(
NonConstantValue::Variable("id".intern().into()),
Span::todo_generated(),
),
},
Location::generated(),
)];

let merged_selection_set = selection_set_wrapped(
nested_merged_selection_set,
*NODE_FIELD_NAME,
id_arguments,
None,
RequiresRefinement::Yes(type_to_refine_to),
);
// TODO we can pre-calculate this instead of re-iterating here
let reachable_variables =
merged_selection_set.reachable_variables();

let mut definitions_of_used_variables =
get_used_variable_definitions(&reachable_variables, entrypoint);

// HACK, we also add the id field
definitions_of_used_variables.push(WithSpan::new(
VariableDefinition {
name: WithLocation::new(
"id".intern().into(),
Location::generated(),
),
type_: GraphQLTypeAnnotation::NonNull(Box::new(
NonNullTypeAnnotation::Named(NamedTypeAnnotation(
WithSpan::new(
SelectableServerFieldId::Scalar(
schema.id_type_id,
),
Span::todo_generated(),
),
)),
)),
},
Span::todo_generated(),
));

artifact_queue.push(ImperativelyLoadedFieldArtifactInfo {
merged_selection_set,
variable_definitions: definitions_of_used_variables,
root_parent_object: schema
.server_field_data
.object(entrypoint.parent_object_id)
.name,
root_fetchable_field: entrypoint.name,
refetch_query_index: RefetchQueryIndex(index as u32),
query_name: format!("{type_to_refine_to}__refetch")
.intern()
.into(),
root_operation_name: RootOperationName("query".to_string()),
});
("__refetch".intern().into(), reachable_variables)
}
ClientFieldVariant::ImperativelyLoadedField(
ImperativelyLoadedFieldVariant {
client_field_scalar_selection_name,
Expand All @@ -347,17 +275,17 @@ pub fn create_merged_selection_set(
root_object_id,
},
) => {
// This could be Pet
let refetch_field_parent_type =
schema.server_field_data.object(refetch_field_parent_id);

// TODO we can pre-calculate this instead of re-iterating here
let reachable_variables =
merged_selection_set.reachable_variables();
let mut reachable_variables =
nested_merged_selection_set.reachable_variables();

let mut definitions_of_used_variables =
get_used_variable_definitions(&reachable_variables, entrypoint);

// It's a bit weird that all exposed fields become imperatively
// loaded fields. It probably makes sense to think about how we
// can name the things in this block better.

let requires_refinement = if primary_field_info
.as_ref()
.map(|x| {
Expand All @@ -366,17 +294,12 @@ pub fn create_merged_selection_set(
})
.unwrap_or(true)
{
RequiresRefinement::Yes(
schema
.server_field_data
.object(refetch_field_parent_id)
.name,
)
RequiresRefinement::Yes(refetch_field_parent_type.name)
} else {
RequiresRefinement::No
};

let merged_selection_set = selection_set_wrapped(
let wrapped_selection_set = selection_set_wrapped(
nested_merged_selection_set,
// TODO why are these types different
top_level_schema_field_name.lookup().intern().into(),
Expand All @@ -403,6 +326,9 @@ pub fn create_merged_selection_set(
},
span: Span::todo_generated(),
});

reachable_variables.insert(variable_name.item);

x.map(|item| SelectionFieldArgument {
name: WithSpan::new(
item.name.item.lookup().intern().into(),
Expand All @@ -428,7 +354,7 @@ pub fn create_merged_selection_set(
.object(entrypoint.parent_object_id)
.name;
artifact_queue.push(ImperativelyLoadedFieldArtifactInfo {
merged_selection_set,
merged_selection_set: wrapped_selection_set,
root_parent_object,
variable_definitions: definitions_of_used_variables,
root_fetchable_field: entrypoint.name,
Expand All @@ -441,9 +367,14 @@ pub fn create_merged_selection_set(
This is indicative of a bug in Isograph.",
)
.clone(),
query_name: format!(
"{root_parent_object}__{client_field_scalar_selection_name}"
)
query_name: if primary_field_info.is_some() {
format!(
"{}__{}",
root_parent_object, client_field_scalar_selection_name
)
} else {
format!("{}__refetch", refetch_field_parent_type.name)
}
.intern()
.into(),
});
Expand All @@ -465,7 +396,7 @@ pub fn create_merged_selection_set(
)
.collect();

(merged_selection_set, root_refetched_paths)
(full_merged_selection_set, root_refetched_paths)
}
None => {
// TODO it is weird that we call this without an artifact queue!
Expand All @@ -474,13 +405,12 @@ pub fn create_merged_selection_set(
.into_iter()
.map(|(path_to_refetch_field, _, client_field_variant)| {
let nested_merged_selection_set =
find_by_path(&merged_selection_set, &path_to_refetch_field);
find_by_path(&full_merged_selection_set, &path_to_refetch_field);

// TODO we can pre-calculate this instead of re-iterating here
let reachable_variables = nested_merged_selection_set.reachable_variables();

let field_name = match client_field_variant {
ClientFieldVariant::RefetchField(_) => "__refetch".intern().into(),
ClientFieldVariant::ImperativelyLoadedField(
ImperativelyLoadedFieldVariant {
client_field_scalar_selection_name: mutation_field_name,
Expand All @@ -502,7 +432,7 @@ pub fn create_merged_selection_set(
})
.collect();

(merged_selection_set, root_refetched_paths)
(full_merged_selection_set, root_refetched_paths)
}
}
}
Expand Down Expand Up @@ -730,16 +660,6 @@ fn merge_scalar_client_field(
}

match &client_field.variant {
ClientFieldVariant::RefetchField(variant) => {
merge_traversal_state.paths_to_refetch_fields.insert((
PathToRefetchField {
linked_fields: merge_traversal_state.current_path.clone(),
field_name: client_field.name,
},
parent_type.id,
ClientFieldVariant::RefetchField(variant.clone()),
));
}
ClientFieldVariant::ImperativelyLoadedField(variant) => {
merge_traversal_state.paths_to_refetch_fields.insert((
PathToRefetchField {
Expand Down

0 comments on commit f7b3e74

Please sign in to comment.