Skip to content

Commit e00eab8

Browse files
committed
filter requested type before sending initial state
1 parent 557276f commit e00eab8

File tree

1 file changed

+95
-3
lines changed

1 file changed

+95
-3
lines changed

src/gql.rs

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use async_graphql::futures_util::future::ready;
22
use async_graphql::futures_util::{Stream, StreamExt, stream};
3-
use async_graphql::{Context, EmptyMutation, Enum, ID, Object, Schema, Subscription, Union};
3+
use async_graphql::parser::types::{FragmentDefinition, Selection, SelectionSet};
4+
use async_graphql::{
5+
Context, EmptyMutation, Enum, ID, Name, Object, Positioned, Schema, Subscription, Union,
6+
};
47
use std::collections::{HashMap, HashSet};
58
use std::sync::{Arc, RwLock};
69
use tokio::sync::broadcast::Sender;
@@ -348,6 +351,91 @@ impl RiverSnapshot {
348351
}
349352
}
350353

354+
fn collect_requested_event_types(
355+
fragments: &HashMap<Name, Positioned<FragmentDefinition>>,
356+
selection_set: &SelectionSet,
357+
out: &mut HashSet<RiverEventType>,
358+
visited: &mut HashSet<Name>,
359+
) {
360+
for selection in &selection_set.items {
361+
match &selection.node {
362+
Selection::Field(field) => {
363+
collect_requested_event_types(
364+
fragments,
365+
&field.node.selection_set.node,
366+
out,
367+
visited,
368+
);
369+
}
370+
Selection::InlineFragment(fragment) => {
371+
if let Some(condition) = &fragment.node.type_condition {
372+
for ty in event_types_for_name(condition.node.on.node.as_str()) {
373+
out.insert(ty);
374+
}
375+
}
376+
collect_requested_event_types(
377+
fragments,
378+
&fragment.node.selection_set.node,
379+
out,
380+
visited,
381+
);
382+
}
383+
Selection::FragmentSpread(spread) => {
384+
let name = spread.node.fragment_name.node.clone();
385+
if !visited.insert(name.clone()) {
386+
continue;
387+
}
388+
if let Some(fragment) = fragments.get(&name) {
389+
for ty in
390+
event_types_for_name(fragment.node.type_condition.node.on.node.as_str())
391+
{
392+
out.insert(ty);
393+
}
394+
collect_requested_event_types(
395+
fragments,
396+
&fragment.node.selection_set.node,
397+
out,
398+
visited,
399+
);
400+
}
401+
}
402+
}
403+
}
404+
}
405+
406+
fn requested_event_types(ctx: &Context<'_>) -> Option<HashSet<RiverEventType>> {
407+
let selection_set = &ctx.item.node.selection_set.node;
408+
if selection_set.items.is_empty() {
409+
return None;
410+
}
411+
let mut out = HashSet::new();
412+
let mut visited = HashSet::new();
413+
collect_requested_event_types(
414+
&ctx.query_env.fragments,
415+
selection_set,
416+
&mut out,
417+
&mut visited,
418+
);
419+
if out.is_empty() { None } else { Some(out) }
420+
}
421+
422+
fn event_types_for_name(name: &str) -> Vec<RiverEventType> {
423+
match name {
424+
"OutputFocusedTags" => vec![RiverEventType::OutputFocusedTags],
425+
"OutputViewTags" => vec![RiverEventType::OutputViewTags],
426+
"OutputUrgentTags" => vec![RiverEventType::OutputUrgentTags],
427+
"OutputLayoutName" => vec![
428+
RiverEventType::OutputLayoutName,
429+
RiverEventType::OutputLayoutNameClear,
430+
],
431+
"SeatFocusedOutput" => vec![RiverEventType::SeatFocusedOutput],
432+
"SeatUnfocusedOutput" => vec![RiverEventType::SeatUnfocusedOutput],
433+
"SeatFocusedView" => vec![RiverEventType::SeatFocusedView],
434+
"SeatMode" => vec![RiverEventType::SeatMode],
435+
_ => Vec::new(),
436+
}
437+
}
438+
351439
pub type RiverStateHandle = Arc<RwLock<RiverSnapshot>>;
352440

353441
pub fn new_river_state() -> RiverStateHandle {
@@ -734,7 +822,9 @@ impl SubscriptionRoot {
734822
let sender = ctx.data_unchecked::<Sender<river::Event>>().clone();
735823
let rx = sender.subscribe();
736824
let include_lists = tag_list.unwrap_or(false);
737-
let tset = types.map(|v| v.into_iter().collect::<HashSet<_>>());
825+
let tset = types
826+
.map(|v| v.into_iter().collect::<HashSet<_>>())
827+
.or_else(|| requested_event_types(ctx));
738828
let initial_events = {
739829
let handle = ctx.data_unchecked::<RiverStateHandle>();
740830
match handle.read() {
@@ -770,7 +860,9 @@ impl SubscriptionRoot {
770860
let sender = ctx.data_unchecked::<Sender<river::Event>>().clone();
771861
let rx = sender.subscribe();
772862
let include_lists = tag_list.unwrap_or(false);
773-
let tset = types.map(|v| v.into_iter().collect::<HashSet<_>>());
863+
let tset = types
864+
.map(|v| v.into_iter().collect::<HashSet<_>>())
865+
.or_else(|| requested_event_types(ctx));
774866
let target_output = output_name;
775867
let initial_events = {
776868
let handle = ctx.data_unchecked::<RiverStateHandle>();

0 commit comments

Comments
 (0)