clients: snapshot

This commit is contained in:
nym21
2026-01-11 23:08:08 +01:00
parent 325811fee7
commit 5826d78e35
38 changed files with 10018 additions and 11139 deletions
@@ -12,7 +12,13 @@ pub fn generate_api_methods(output: &mut String, endpoints: &[Endpoint]) {
}
let method_name = endpoint_to_method_name(endpoint);
let return_type = normalize_return_type(endpoint.response_type.as_deref().unwrap_or("*"));
let base_return_type =
normalize_return_type(endpoint.response_type.as_deref().unwrap_or("*"));
let return_type = if endpoint.supports_csv {
format!("{} | string", base_return_type)
} else {
base_return_type
};
writeln!(output, " /**").unwrap();
if let Some(summary) = &endpoint.summary {
@@ -58,7 +64,7 @@ pub fn generate_api_methods(output: &mut String, endpoints: &[Endpoint]) {
let path = build_path_template(&endpoint.path, &endpoint.path_params);
if endpoint.query_params.is_empty() {
writeln!(output, " return this.get(`{}`);", path).unwrap();
writeln!(output, " return this.getJson(`{}`);", path).unwrap();
} else {
writeln!(output, " const params = new URLSearchParams();").unwrap();
for param in &endpoint.query_params {
@@ -79,12 +85,16 @@ pub fn generate_api_methods(output: &mut String, endpoints: &[Endpoint]) {
}
}
writeln!(output, " const query = params.toString();").unwrap();
writeln!(
output,
" return this.get(`{}${{query ? '?' + query : ''}}`);",
path
)
.unwrap();
writeln!(output, " const path = `{}${{query ? '?' + query : ''}}`;", path).unwrap();
if endpoint.supports_csv {
writeln!(output, " if (format === 'csv') {{").unwrap();
writeln!(output, " return this.getText(path);").unwrap();
writeln!(output, " }}").unwrap();
writeln!(output, " return this.getJson(path);").unwrap();
} else {
writeln!(output, " return this.getJson(path);").unwrap();
}
}
writeln!(output, " }}\n").unwrap();
@@ -52,8 +52,8 @@ class BrkError extends Error {{
* @template T
* @typedef {{Object}} MetricData
* @property {{number}} total - Total number of data points
* @property {{number}} from - Start index (inclusive)
* @property {{number}} to - End index (exclusive)
* @property {{number}} start - Start index (inclusive)
* @property {{number}} end - End index (exclusive)
* @property {{T[]}} data - The metric data
*/
/** @typedef {{MetricData<unknown>}} AnyMetricData */
@@ -62,7 +62,7 @@ class BrkError extends Error {{
* @template T
* @typedef {{Object}} MetricEndpoint
* @property {{(onUpdate?: (value: MetricData<T>) => void) => Promise<MetricData<T>>}} get - Fetch all data points
* @property {{(from?: number, to?: number, onUpdate?: (value: MetricData<T>) => void) => Promise<MetricData<T>>}} range - Fetch data in range
* @property {{(start?: number, end?: number, onUpdate?: (value: MetricData<T>) => void) => Promise<MetricData<T>>}} range - Fetch data in range
* @property {{string}} path - The endpoint path
*/
/** @typedef {{MetricEndpoint<unknown>}} AnyMetricEndpoint */
@@ -89,13 +89,13 @@ class BrkError extends Error {{
function _endpoint(client, name, index) {{
const p = `/api/metric/${{name}}/${{index}}`;
return {{
get: (onUpdate) => client.get(p, onUpdate),
range: (from, to, onUpdate) => {{
get: (onUpdate) => client.getJson(p, onUpdate),
range: (start, end, onUpdate) => {{
const params = new URLSearchParams();
if (from !== undefined) params.set('from', String(from));
if (to !== undefined) params.set('to', String(to));
if (start !== undefined) params.set('start', String(start));
if (end !== undefined) params.set('end', String(end));
const query = params.toString();
return client.get(query ? `${{p}}?${{query}}` : p, onUpdate);
return client.getJson(query ? `${{p}}?${{query}}` : p, onUpdate);
}},
get path() {{ return p; }},
}};
@@ -114,6 +114,18 @@ class BrkClientBase {{
this.timeout = isString ? 5000 : (options.timeout ?? 5000);
}}
/**
* @param {{string}} path
* @returns {{Promise<Response>}}
*/
async get(path) {{
const base = this.baseUrl.endsWith('/') ? this.baseUrl.slice(0, -1) : this.baseUrl;
const url = `${{base}}${{path}}`;
const res = await fetch(url, {{ signal: AbortSignal.timeout(this.timeout) }});
if (!res.ok) throw new BrkError(`HTTP ${{res.status}}`, res.status);
return res;
}}
/**
* Make a GET request with stale-while-revalidate caching
* @template T
@@ -121,7 +133,7 @@ class BrkClientBase {{
* @param {{(value: T) => void}} [onUpdate] - Called when data is available
* @returns {{Promise<T>}}
*/
async get(path, onUpdate) {{
async getJson(path, onUpdate) {{
const base = this.baseUrl.endsWith('/') ? this.baseUrl.slice(0, -1) : this.baseUrl;
const url = `${{base}}${{path}}`;
const cache = await _cachePromise;
@@ -135,8 +147,7 @@ class BrkClientBase {{
}}
try {{
const res = await fetch(url, {{ signal: AbortSignal.timeout(this.timeout) }});
if (!res.ok) throw new BrkError(`HTTP ${{res.status}}`, res.status);
const res = await this.get(path);
if (cachedRes?.headers.get('ETag') === res.headers.get('ETag')) return cachedJson;
const cloned = res.clone();
@@ -149,6 +160,16 @@ class BrkClientBase {{
throw e;
}}
}}
/**
* Make a GET request and return raw text (for CSV responses)
* @param {{string}} path
* @returns {{Promise<string>}}
*/
async getText(path) {{
const res = await this.get(path);
return res.text();
}}
}}
/**
@@ -14,7 +14,7 @@ use crate::{
use super::api::generate_api_methods;
use super::client::generate_static_constants;
/// Generate JSDoc typedefs for the catalog tree.
/// Generate JSDoc typedefs for the metrics tree.
pub fn generate_tree_typedefs(output: &mut String, catalog: &TreeNode, metadata: &ClientMetadata) {
writeln!(output, "// Catalog tree typedefs\n").unwrap();
@@ -22,7 +22,7 @@ pub fn generate_tree_typedefs(output: &mut String, catalog: &TreeNode, metadata:
let mut generated = HashSet::new();
generate_tree_typedef(
output,
"CatalogTree",
"MetricsTree",
catalog,
&pattern_lookup,
metadata,
@@ -98,7 +98,7 @@ pub fn generate_main_client(
writeln!(output, "/**").unwrap();
writeln!(
output,
" * Main BRK client with catalog tree and API methods"
" * Main BRK client with metrics tree and API methods"
)
.unwrap();
writeln!(output, " * @extends BrkClientBase").unwrap();
@@ -112,14 +112,14 @@ pub fn generate_main_client(
writeln!(output, " */").unwrap();
writeln!(output, " constructor(options) {{").unwrap();
writeln!(output, " super(options);").unwrap();
writeln!(output, " /** @type {{CatalogTree}} */").unwrap();
writeln!(output, " this.tree = this._buildTree('');").unwrap();
writeln!(output, " /** @type {{MetricsTree}} */").unwrap();
writeln!(output, " this.metrics = this._buildTree('');").unwrap();
writeln!(output, " }}\n").unwrap();
writeln!(output, " /**").unwrap();
writeln!(output, " * @private").unwrap();
writeln!(output, " * @param {{string}} basePath").unwrap();
writeln!(output, " * @returns {{CatalogTree}}").unwrap();
writeln!(output, " * @returns {{MetricsTree}}").unwrap();
writeln!(output, " */").unwrap();
writeln!(output, " _buildTree(basePath) {{").unwrap();
writeln!(output, " return {{").unwrap();