clients: snapshot

This commit is contained in:
nym21
2026-01-14 01:20:25 +01:00
parent 3a836ab0f4
commit 25a0ebe51e
10 changed files with 7218 additions and 3920 deletions

View File

@@ -6,9 +6,8 @@ use std::fmt::Write;
use brk_types::TreeNode;
use crate::{
ClientMetadata, Endpoint, GenericSyntax, JavaScriptSyntax, PatternField,
generate_leaf_field, get_first_leaf_name, get_node_fields, get_pattern_instance_base,
infer_accumulated_name, prepare_tree_node, to_camel_case,
ClientMetadata, Endpoint, GenericSyntax, JavaScriptSyntax, PatternField, generate_leaf_field,
prepare_tree_node, to_camel_case,
};
use super::api::generate_api_methods;
@@ -121,15 +120,36 @@ pub fn generate_main_client(
writeln!(output, " */").unwrap();
writeln!(output, " _buildTree(basePath) {{").unwrap();
writeln!(output, " return {{").unwrap();
generate_tree_initializer(output, catalog, "", 3, &pattern_lookup, metadata);
let mut generated = HashSet::new();
generate_tree_initializer(
output,
catalog,
"MetricsTree",
3,
&pattern_lookup,
metadata,
&mut generated,
);
writeln!(output, " }};").unwrap();
writeln!(output, " }}\n").unwrap();
writeln!(output, " /**").unwrap();
writeln!(output, " * Create a dynamic metric endpoint builder for any metric/index combination.").unwrap();
writeln!(
output,
" * Create a dynamic metric endpoint builder for any metric/index combination."
)
.unwrap();
writeln!(output, " *").unwrap();
writeln!(output, " * Use this for programmatic access when the metric name is determined at runtime.").unwrap();
writeln!(output, " * For type-safe access, use the `metrics` tree instead.").unwrap();
writeln!(
output,
" * Use this for programmatic access when the metric name is determined at runtime."
)
.unwrap();
writeln!(
output,
" * For type-safe access, use the `metrics` tree instead."
)
.unwrap();
writeln!(output, " *").unwrap();
writeln!(output, " * @param {{string}} metric - The metric name").unwrap();
writeln!(output, " * @param {{Index}} index - The index name").unwrap();
@@ -149,66 +169,55 @@ pub fn generate_main_client(
fn generate_tree_initializer(
output: &mut String,
node: &TreeNode,
accumulated_name: &str,
name: &str,
indent: usize,
pattern_lookup: &std::collections::HashMap<Vec<PatternField>, String>,
metadata: &ClientMetadata,
generated: &mut HashSet<String>,
) {
let indent_str = " ".repeat(indent);
let Some(ctx) = prepare_tree_node(node, name, pattern_lookup, metadata, generated) else {
return;
};
let syntax = JavaScriptSyntax;
if let TreeNode::Branch(children) = node {
for (child_name, child_node) in children.iter() {
match child_node {
TreeNode::Leaf(leaf) => {
// Use shared helper for leaf fields
generate_leaf_field(
output,
&syntax,
"this",
child_name,
leaf,
metadata,
&indent_str,
);
}
TreeNode::Branch(grandchildren) => {
let field_name = to_camel_case(child_name);
let child_fields = get_node_fields(grandchildren, pattern_lookup);
// Use pattern factory if ANY pattern matches (not just parameterizable)
let pattern_name = pattern_lookup.get(&child_fields);
for child in &ctx.children {
let field_name = to_camel_case(child.name);
let base_result = get_pattern_instance_base(child_node);
// Use pattern factory only if no outlier was detected
if let Some(pattern_name) = pattern_name.filter(|_| !base_result.has_outlier) {
writeln!(
output,
"{}{}: create{}(this, '{}'),",
indent_str, field_name, pattern_name, base_result.base
)
.unwrap();
} else {
let child_acc =
infer_child_accumulated_name(child_node, accumulated_name, child_name);
writeln!(output, "{}{}: {{", indent_str, field_name).unwrap();
generate_tree_initializer(
output,
child_node,
&child_acc,
indent + 1,
pattern_lookup,
metadata,
);
writeln!(output, "{}}},", indent_str).unwrap();
}
}
if child.is_leaf {
if let TreeNode::Leaf(leaf) = child.node {
generate_leaf_field(
output,
&syntax,
"this",
child.name,
leaf,
metadata,
&indent_str,
);
}
} else if child.should_inline {
// Inline object
writeln!(output, "{}{}: {{", indent_str, field_name).unwrap();
generate_tree_initializer(
output,
child.node,
&child.inline_type_name,
indent + 1,
pattern_lookup,
metadata,
generated,
);
writeln!(output, "{}}},", indent_str).unwrap();
} else {
// Use pattern factory
writeln!(
output,
"{}{}: create{}(this, '{}'),",
indent_str, field_name, child.field.rust_type, child.base_result.base
)
.unwrap();
}
}
}
fn infer_child_accumulated_name(node: &TreeNode, parent_acc: &str, field_name: &str) -> String {
let leaf_name = get_first_leaf_name(node).unwrap_or_default();
infer_accumulated_name(parent_acc, field_name, &leaf_name)
}