use crate::app::AppConfig; use crate::context::RequestContext; use crate::error::WebError; use crate::routes::query_support::{ execute_runtime_query_against_data, reject_non_local_query_data, }; use bridge_runtime::RuntimeQueryEnvelopeWire; use core_protocol::{KernelNodeType, KernelProjectionKind}; use serde_json::{json, Value}; #[derive(Debug, Clone)] pub struct ProjectionSnapshotSpec<'a> { pub workspace_id: &'a str, pub root_node_id: Option<&'a str>, pub depth: Option, pub query: Option<&'a str>, pub max_results: Option, pub projection: KernelProjectionKind, } #[derive(Debug, Clone)] pub struct ProjectionSnapshot { pub dataset: Value, pub projection: Value, } pub fn sidebar_dataset_query(workspace_id: &str) -> RuntimeQueryEnvelopeWire { RuntimeQueryEnvelopeWire { name: "sidebar.dataset.list".into(), payload: json!({ "workspaceId": workspace_id, }), } } pub async fn load_sidebar_dataset( config: &AppConfig, context: &RequestContext, workspace_id: &str, ) -> Result { reject_non_local_query_data( config, context, Some(workspace_id), sidebar_dataset_query(workspace_id), ) .await } pub fn projection_query(spec: &ProjectionSnapshotSpec<'_>) -> RuntimeQueryEnvelopeWire { RuntimeQueryEnvelopeWire { name: "kernel.project_view".into(), payload: json!({ "projection": spec.projection, "workspaceId": spec.workspace_id, "rootNodeId": spec.root_node_id, "depth": spec.depth, "query": spec.query, "maxResults": spec.max_results, "includeEdges": true, "includeContent": false, "nodeTypes": [KernelNodeType::Page], }), } } pub fn subtree_query( workspace_id: &str, root_node_id: &str, depth: Option, ) -> RuntimeQueryEnvelopeWire { RuntimeQueryEnvelopeWire { name: "kernel.subtree.get".into(), payload: json!({ "workspaceId": workspace_id, "rootNodeId": root_node_id, "depth": depth, "includeEdges": true, "nodeTypes": [KernelNodeType::Page], }), } } pub fn execute_kernel_query( context: &RequestContext, workspace_id: &str, query: RuntimeQueryEnvelopeWire, dataset: Value, ) -> Result { execute_runtime_query_against_data(context, Some(workspace_id), query, dataset) } pub async fn load_projection_snapshot( config: &AppConfig, context: &RequestContext, spec: &ProjectionSnapshotSpec<'_>, ) -> Result { let dataset = load_sidebar_dataset(config, context, spec.workspace_id).await?; let projection = execute_kernel_query( context, spec.workspace_id, projection_query(spec), dataset.clone(), )?; Ok(ProjectionSnapshot { dataset, projection, }) }