mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-25 15:19:58 -07:00
global: snapshot
This commit is contained in:
@@ -1,29 +1,30 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use axum::{
|
||||
Json,
|
||||
body::Body,
|
||||
extract::{Query, State},
|
||||
http::{HeaderMap, StatusCode},
|
||||
http::{HeaderMap, StatusCode, Uri},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use brk_error::{Error, Result};
|
||||
use brk_interface::{Format, Output, Params};
|
||||
use brk_vecs::Stamp;
|
||||
use quick_cache::sync::GuardResult;
|
||||
|
||||
use crate::traits::{HeaderMapExtended, ResponseExtended};
|
||||
use crate::{HeaderMapExtended, ResponseExtended};
|
||||
|
||||
use super::AppState;
|
||||
|
||||
mod bridge;
|
||||
|
||||
pub use bridge::*;
|
||||
|
||||
const MAX_WEIGHT: usize = 320_000;
|
||||
|
||||
pub async fn handler(
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
query: Query<Params>,
|
||||
State(app_state): State<AppState>,
|
||||
) -> Response {
|
||||
match req_to_response_res(headers, query, app_state) {
|
||||
match req_to_response_res(uri, headers, query, app_state) {
|
||||
Ok(response) => response,
|
||||
Err(error) => {
|
||||
let mut response =
|
||||
@@ -35,9 +36,12 @@ pub async fn handler(
|
||||
}
|
||||
|
||||
fn req_to_response_res(
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
Query(params): Query<Params>,
|
||||
AppState { interface, .. }: AppState,
|
||||
AppState {
|
||||
interface, cache, ..
|
||||
}: AppState,
|
||||
) -> Result<Response> {
|
||||
let vecs = interface.search(¶ms);
|
||||
|
||||
@@ -67,7 +71,7 @@ fn req_to_response_res(
|
||||
.first()
|
||||
.unwrap()
|
||||
.1
|
||||
.etag(Stamp::from(u64::from(interface.get_height())), to);
|
||||
.etag(Stamp::from(interface.get_height()), to);
|
||||
|
||||
if headers
|
||||
.get_if_none_match()
|
||||
@@ -76,17 +80,51 @@ fn req_to_response_res(
|
||||
return Ok(Response::new_not_modified());
|
||||
}
|
||||
|
||||
let output = interface.format(vecs, ¶ms.rest)?;
|
||||
let guard_res = cache.get_value_or_guard(
|
||||
&format!("{}{}{etag}", uri.path(), uri.query().unwrap_or("")),
|
||||
Some(Duration::from_millis(500)),
|
||||
);
|
||||
|
||||
let mut response = match output {
|
||||
Output::CSV(s) => s.into_response(),
|
||||
Output::TSV(s) => s.into_response(),
|
||||
Output::Json(v) => match v {
|
||||
brk_interface::Value::Single(v) => Json(v).into_response(),
|
||||
brk_interface::Value::List(v) => Json(v).into_response(),
|
||||
brk_interface::Value::Matrix(v) => Json(v).into_response(),
|
||||
},
|
||||
Output::MD(s) => s.into_response(),
|
||||
let mut response = if let GuardResult::Value(v) = guard_res {
|
||||
Response::new(Body::from(v))
|
||||
} else {
|
||||
match interface.format(vecs, ¶ms.rest)? {
|
||||
Output::CSV(s) => {
|
||||
if let GuardResult::Guard(g) = guard_res {
|
||||
g.insert(s.clone().into())
|
||||
.map_err(|_| Error::QuickCacheError)?;
|
||||
}
|
||||
s.into_response()
|
||||
}
|
||||
Output::TSV(s) => {
|
||||
if let GuardResult::Guard(g) = guard_res {
|
||||
g.insert(s.clone().into())
|
||||
.map_err(|_| Error::QuickCacheError)?;
|
||||
}
|
||||
s.into_response()
|
||||
}
|
||||
Output::MD(s) => {
|
||||
if let GuardResult::Guard(g) = guard_res {
|
||||
g.insert(s.clone().into())
|
||||
.map_err(|_| Error::QuickCacheError)?;
|
||||
}
|
||||
s.into_response()
|
||||
}
|
||||
Output::Json(v) => {
|
||||
let json = match v {
|
||||
brk_interface::Value::Single(v) => serde_json::to_vec(&v)?,
|
||||
brk_interface::Value::List(v) => serde_json::to_vec(&v)?,
|
||||
brk_interface::Value::Matrix(v) => serde_json::to_vec(&v)?,
|
||||
};
|
||||
|
||||
if let GuardResult::Guard(g) = guard_res {
|
||||
g.insert(json.clone().into())
|
||||
.map_err(|_| Error::QuickCacheError)?;
|
||||
}
|
||||
|
||||
json.into_response()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let headers = response.headers_mut();
|
||||
@@ -1,110 +0,0 @@
|
||||
use std::{fs, io, path::Path};
|
||||
|
||||
use brk_interface::{Index, Interface};
|
||||
|
||||
use crate::{VERSION, Website};
|
||||
|
||||
const SCRIPTS: &str = "scripts";
|
||||
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub trait Bridge {
|
||||
fn generate_bridge_file(&self, website: Website, websites_path: &Path) -> io::Result<()>;
|
||||
}
|
||||
|
||||
impl Bridge for Interface<'static> {
|
||||
fn generate_bridge_file(&self, website: Website, websites_path: &Path) -> io::Result<()> {
|
||||
if website.is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let path = websites_path.join(website.to_folder_name());
|
||||
|
||||
if !fs::exists(&path)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let path = path.join(SCRIPTS);
|
||||
|
||||
fs::create_dir_all(&path)?;
|
||||
|
||||
let path = path.join(Path::new("vecid-to-indexes.js"));
|
||||
|
||||
let indexes = Index::all();
|
||||
|
||||
let mut contents = format!(
|
||||
"//
|
||||
// File auto-generated, any modifications will be overwritten
|
||||
//
|
||||
|
||||
export const VERSION = \"v{VERSION}\";
|
||||
|
||||
"
|
||||
);
|
||||
|
||||
contents += &indexes
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i_of_i, i)| {
|
||||
// let lowered = i.to_string().to_lowercase();
|
||||
format!("/** @typedef {{{i_of_i}}} {i} */",)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
contents += &format!(
|
||||
"\n\n/** @typedef {{{}}} Index */\n",
|
||||
indexes
|
||||
.iter()
|
||||
.map(|i| i.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" | ")
|
||||
);
|
||||
|
||||
contents += "
|
||||
/** @typedef {ReturnType<typeof createIndexes>} Indexes */
|
||||
|
||||
export function createIndexes() {
|
||||
return {
|
||||
";
|
||||
|
||||
contents += &indexes
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i_of_i, i)| {
|
||||
let lowered = i.to_string().to_lowercase();
|
||||
format!(" {lowered}: /** @satisfies {{{i}}} */ ({i_of_i}),",)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
contents += " };\n}\n";
|
||||
|
||||
contents += "
|
||||
/** @typedef {ReturnType<typeof createVecIdToIndexes>} VecIdToIndexes
|
||||
/** @typedef {keyof VecIdToIndexes} VecId */
|
||||
|
||||
/**
|
||||
* @returns {Record<any, number[]>}
|
||||
*/
|
||||
export function createVecIdToIndexes() {
|
||||
return {
|
||||
";
|
||||
|
||||
self.id_to_index_to_vec()
|
||||
.iter()
|
||||
.for_each(|(id, index_to_vec)| {
|
||||
let indexes = index_to_vec
|
||||
.keys()
|
||||
.map(|i| (*i as u8).to_string())
|
||||
// .map(|i| i.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
contents += &format!(" \"{id}\": [{indexes}],\n");
|
||||
});
|
||||
|
||||
contents += " };\n}\n";
|
||||
|
||||
fs::write(path, contents)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
use axum::{
|
||||
Json, Router,
|
||||
extract::{Path, Query, State},
|
||||
http::HeaderMap,
|
||||
http::{HeaderMap, Uri},
|
||||
response::{IntoResponse, Redirect, Response},
|
||||
routing::get,
|
||||
};
|
||||
@@ -12,8 +12,6 @@ use super::AppState;
|
||||
mod explorer;
|
||||
mod interface;
|
||||
|
||||
pub use interface::Bridge;
|
||||
|
||||
pub trait ApiRoutes {
|
||||
fn add_api_routes(self) -> Self;
|
||||
}
|
||||
@@ -87,7 +85,8 @@ impl ApiRoutes for Router<AppState> {
|
||||
.route(
|
||||
"/api/vecs/{variant}",
|
||||
get(
|
||||
async |headers: HeaderMap,
|
||||
async |uri: Uri,
|
||||
headers: HeaderMap,
|
||||
Path(variant): Path<String>,
|
||||
Query(params_opt): Query<ParamsOpt>,
|
||||
state: State<AppState>|
|
||||
@@ -100,7 +99,7 @@ impl ApiRoutes for Router<AppState> {
|
||||
(index, split.collect::<Vec<_>>().join(TO_SEPARATOR)),
|
||||
params_opt,
|
||||
));
|
||||
interface::handler(headers, Query(params), state).await
|
||||
interface::handler(uri, headers, Query(params), state).await
|
||||
} else {
|
||||
"Bad variant".into_response()
|
||||
}
|
||||
@@ -127,22 +126,3 @@ impl ApiRoutes for Router<AppState> {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// pub async fn variants_handler(State(app_state): State<AppState>) -> Response {
|
||||
// Json(
|
||||
// app_state
|
||||
// .query
|
||||
// .vec_trees
|
||||
// .index_to_id_to_vec
|
||||
// .iter()
|
||||
// .flat_map(|(index, id_to_vec)| {
|
||||
// let index_ser = index.serialize_long();
|
||||
// id_to_vec
|
||||
// .keys()
|
||||
// .map(|id| format!("{}-to-{}", index_ser, id))
|
||||
// .collect::<Vec<_>>()
|
||||
// })
|
||||
// .collect::<Vec<_>>(),
|
||||
// )
|
||||
// .into_response()
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user