chore: JSPG Engine tuple decoupling and core routing optimizations

This commit is contained in:
2026-04-13 22:41:32 -04:00
parent 665a821bf9
commit 0017c598e1
57 changed files with 5510 additions and 5166 deletions

View File

@ -1,7 +1,7 @@
use crate::database::object::*;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::sync::Arc;
use crate::database::object::*;
#[derive(Debug, Clone, Serialize, Default)]
pub struct Schema {
#[serde(flatten)]
@ -26,6 +26,8 @@ impl Schema {
pub fn compile(
&self,
db: &crate::database::Database,
root_id: &str,
path: String,
visited: &mut std::collections::HashSet<String>,
errors: &mut Vec<crate::drop::Error>,
) {
@ -33,9 +35,11 @@ impl Schema {
return;
}
if let Some(id) = &self.obj.id {
if !visited.insert(id.clone()) {
return; // Break cyclical resolution
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &self.obj.type_ {
if !crate::database::object::is_primitive_type(t) {
if !visited.insert(t.clone()) {
return; // Break cyclical resolution
}
}
}
@ -75,7 +79,7 @@ impl Schema {
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &self.obj.type_ {
if !crate::database::object::is_primitive_type(t) {
if let Some(parent) = db.schemas.get(t) {
parent.as_ref().compile(db, visited, errors);
parent.as_ref().compile(db, t, t.clone(), visited, errors);
if let Some(p_props) = parent.obj.compiled_properties.get() {
props.extend(p_props.clone());
}
@ -95,11 +99,12 @@ impl Schema {
errors.push(crate::drop::Error {
code: "MULTIPLE_INHERITANCE_PROHIBITED".to_string(),
message: format!(
"Schema '{}' attempts to extend multiple custom object pointers in its type array. Use 'oneOf' for polymorphism and tagged unions.",
self.obj.identifier().unwrap_or("unknown".to_string())
"Schema attempts to extend multiple custom object pointers in its type array {:?}. Use 'oneOf' for polymorphism and tagged unions.",
types
),
details: crate::drop::ErrorDetails {
path: self.obj.identifier().unwrap_or("unknown".to_string()),
path: path.clone(),
schema: Some(root_id.to_string()),
..Default::default()
}
});
@ -108,7 +113,7 @@ impl Schema {
for t in types {
if !crate::database::object::is_primitive_type(t) {
if let Some(parent) = db.schemas.get(t) {
parent.as_ref().compile(db, visited, errors);
parent.as_ref().compile(db, t, t.clone(), visited, errors);
}
}
}
@ -128,60 +133,68 @@ impl Schema {
let _ = self.obj.compiled_property_names.set(names);
// 4. Compute Edges natively
let schema_edges = self.compile_edges(db, visited, &props, errors);
let schema_edges = self.compile_edges(db, root_id, &path, visited, &props, errors);
let _ = self.obj.compiled_edges.set(schema_edges);
// 5. Build our inline children properties recursively NOW! (Depth-first search)
if let Some(local_props) = &self.obj.properties {
for child in local_props.values() {
child.compile(db, visited, errors);
for (k, child) in local_props {
child.compile(db, root_id, format!("{}/{}", path, k), visited, errors);
}
}
if let Some(items) = &self.obj.items {
items.compile(db, visited, errors);
items.compile(db, root_id, format!("{}/items", path), visited, errors);
}
if let Some(pattern_props) = &self.obj.pattern_properties {
for child in pattern_props.values() {
child.compile(db, visited, errors);
for (k, child) in pattern_props {
child.compile(db, root_id, format!("{}/{}", path, k), visited, errors);
}
}
if let Some(additional_props) = &self.obj.additional_properties {
additional_props.compile(db, visited, errors);
additional_props.compile(
db,
root_id,
format!("{}/additionalProperties", path),
visited,
errors,
);
}
if let Some(one_of) = &self.obj.one_of {
for child in one_of {
child.compile(db, visited, errors);
for (i, child) in one_of.iter().enumerate() {
child.compile(db, root_id, format!("{}/oneOf/{}", path, i), visited, errors);
}
}
if let Some(arr) = &self.obj.prefix_items {
for child in arr {
child.compile(db, visited, errors);
for (i, child) in arr.iter().enumerate() {
child.compile(db, root_id, format!("{}/prefixItems/{}", path, i), visited, errors);
}
}
if let Some(child) = &self.obj.not {
child.compile(db, visited, errors);
child.compile(db, root_id, format!("{}/not", path), visited, errors);
}
if let Some(child) = &self.obj.contains {
child.compile(db, visited, errors);
child.compile(db, root_id, format!("{}/contains", path), visited, errors);
}
if let Some(cases) = &self.obj.cases {
for c in cases {
for (i, c) in cases.iter().enumerate() {
if let Some(child) = &c.when {
child.compile(db, visited, errors);
child.compile(db, root_id, format!("{}/cases/{}/when", path, i), visited, errors);
}
if let Some(child) = &c.then {
child.compile(db, visited, errors);
child.compile(db, root_id, format!("{}/cases/{}/then", path, i), visited, errors);
}
if let Some(child) = &c.else_ {
child.compile(db, visited, errors);
child.compile(db, root_id, format!("{}/cases/{}/else", path, i), visited, errors);
}
}
}
self.compile_polymorphism(db, errors);
self.compile_polymorphism(db, root_id, &path, errors);
if let Some(id) = &self.obj.id {
visited.remove(id);
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &self.obj.type_ {
if !crate::database::object::is_primitive_type(t) {
visited.remove(t);
}
}
}
@ -192,6 +205,8 @@ impl Schema {
pub fn compile_edges(
&self,
db: &crate::database::Database,
root_id: &str,
path: &str,
visited: &mut std::collections::HashSet<String>,
props: &std::collections::BTreeMap<String, std::sync::Arc<Schema>>,
errors: &mut Vec<crate::drop::Error>,
@ -201,16 +216,33 @@ impl Schema {
// Determine the physical Database Table Name this schema structurally represents
// Plucks the polymorphic discriminator via dot-notation (e.g. extracting "person" from "full.person")
let mut parent_type_name = None;
if let Some(family) = &self.obj.family {
// 1. Explicit horizontal routing
parent_type_name = Some(family.split('.').next_back().unwrap_or(family).to_string());
} else if let Some(identifier) = self.obj.identifier() {
parent_type_name = Some(
identifier
.split('.')
.next_back()
.unwrap_or(&identifier)
.to_string(),
);
} else if !path.contains('/') {
// 2. Root nodes trust their exact registry footprint
let base_type_name = path.split('.').next_back().unwrap_or(path).to_string();
if db.types.contains_key(&base_type_name) {
parent_type_name = Some(base_type_name);
}
} else if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &self.obj.type_ {
// 3. Nested graphs trust their explicit struct pointer reference
if !crate::database::object::is_primitive_type(t) {
parent_type_name = Some(t.split('.').next_back().unwrap_or(t).to_string());
}
}
if parent_type_name.is_none() {
// 4. Absolute fallback for completely anonymous inline structures
let base_type_name = root_id
.split('.')
.next_back()
.unwrap_or(root_id)
.to_string();
if db.types.contains_key(&base_type_name) {
parent_type_name = Some(base_type_name);
}
}
if let Some(p_type) = parent_type_name {
@ -237,13 +269,19 @@ impl Schema {
// Determine the physical Postgres table backing the nested child schema recursively
if let Some(family) = &target_schema.obj.family {
child_type_name = Some(family.split('.').next_back().unwrap_or(family).to_string());
} else if let Some(ref_id) = target_schema.obj.identifier() {
child_type_name = Some(ref_id.split('.').next_back().unwrap_or(&ref_id).to_string());
} else if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) =
&target_schema.obj.type_
{
if !crate::database::object::is_primitive_type(t) {
child_type_name = Some(t.split('.').next_back().unwrap_or(t).to_string());
}
} else if let Some(arr) = &target_schema.obj.one_of {
if let Some(first) = arr.first() {
if let Some(ref_id) = first.obj.identifier() {
child_type_name =
Some(ref_id.split('.').next_back().unwrap_or(&ref_id).to_string());
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &first.obj.type_
{
if !crate::database::object::is_primitive_type(t) {
child_type_name = Some(t.split('.').next_back().unwrap_or(t).to_string());
}
}
}
}
@ -252,7 +290,7 @@ impl Schema {
if db.types.contains_key(&c_type) {
// Ensure the child Schema's AST has accurately compiled its own physical property keys so we can
// inject them securely for Many-to-Many Twin Deduction disambiguation matching.
target_schema.compile(db, visited, errors);
target_schema.compile(db, root_id, format!("{}/{}", path, prop_name), visited, errors);
if let Some(compiled_target_props) = target_schema.obj.compiled_properties.get() {
let keys_for_ambiguity: Vec<String> =
compiled_target_props.keys().cloned().collect();
@ -264,8 +302,8 @@ impl Schema {
prop_name,
Some(&keys_for_ambiguity),
is_array,
self.id.as_deref(),
&format!("/{}", prop_name),
Some(root_id),
&format!("{}/{}", path, prop_name),
errors,
) {
schema_edges.insert(
@ -288,6 +326,8 @@ impl Schema {
pub fn compile_polymorphism(
&self,
db: &crate::database::Database,
root_id: &str,
path: &str,
errors: &mut Vec<crate::drop::Error>,
) {
let mut options = std::collections::BTreeMap::new();
@ -312,7 +352,7 @@ impl Schema {
};
if db.schemas.contains_key(&target_id) {
options.insert(var.to_string(), target_id);
options.insert(var.to_string(), (None, Some(target_id)));
}
}
} else {
@ -321,12 +361,10 @@ impl Schema {
let suffix = format!(".{}", family_base);
for schema in &type_def.schemas {
if let Some(id) = &schema.obj.id {
if id.ends_with(&suffix) || id == &family_base {
if let Some(kind_val) = schema.obj.get_discriminator_value("kind") {
options.insert(kind_val, id.to_string());
}
for (id, schema) in &type_def.schemas {
if id.ends_with(&suffix) || id == &family_base {
if let Some(kind_val) = schema.obj.get_discriminator_value("kind", id) {
options.insert(kind_val, (None, Some(id.to_string())));
}
}
}
@ -335,65 +373,114 @@ impl Schema {
} else if let Some(one_of) = &self.obj.one_of {
let mut type_vals = std::collections::HashSet::new();
let mut kind_vals = std::collections::HashSet::new();
let mut disjoint_base = true;
let mut structural_types = std::collections::HashSet::new();
for c in one_of {
if let Some(t_val) = c.obj.get_discriminator_value("type") {
type_vals.insert(t_val);
let mut child_id = String::new();
let mut child_is_primitive = false;
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &c.obj.type_ {
if crate::database::object::is_primitive_type(t) {
child_is_primitive = true;
structural_types.insert(t.clone());
} else {
child_id = t.clone();
structural_types.insert("object".to_string());
}
} else {
disjoint_base = false;
}
if let Some(k_val) = c.obj.get_discriminator_value("kind") {
kind_vals.insert(k_val);
if !child_is_primitive {
if let Some(t_val) = c.obj.get_discriminator_value("type", &child_id) {
type_vals.insert(t_val);
}
if let Some(k_val) = c.obj.get_discriminator_value("kind", &child_id) {
kind_vals.insert(k_val);
}
}
}
strategy = if type_vals.len() > 1 && type_vals.len() == one_of.len() {
"type".to_string()
} else if kind_vals.len() > 1 && kind_vals.len() == one_of.len() {
"kind".to_string()
if disjoint_base && structural_types.len() == one_of.len() {
strategy = "".to_string();
for (i, c) in one_of.iter().enumerate() {
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &c.obj.type_ {
if crate::database::object::is_primitive_type(t) {
options.insert(t.clone(), (Some(i), None));
} else {
options.insert("object".to_string(), (Some(i), None));
}
}
}
} else {
"".to_string()
};
strategy = if type_vals.len() > 1 && type_vals.len() == one_of.len() {
"type".to_string()
} else if kind_vals.len() > 1 && kind_vals.len() == one_of.len() {
"kind".to_string()
} else {
"".to_string()
};
if strategy.is_empty() {
return;
}
for c in one_of {
if let Some(val) = c.obj.get_discriminator_value(&strategy) {
if options.contains_key(&val) {
errors.push(crate::drop::Error {
code: "POLYMORPHIC_COLLISION".to_string(),
message: format!("Polymorphic boundary defines multiple candidates mapped to the identical discriminator value '{}'.", val),
details: crate::drop::ErrorDetails::default()
});
continue;
if strategy.is_empty() {
errors.push(crate::drop::Error {
code: "AMBIGUOUS_POLYMORPHISM".to_string(),
message: format!("oneOf boundaries must map mathematically unique 'type' or 'kind' discriminators, or strictly contain disjoint primitive types."),
details: crate::drop::ErrorDetails {
path: path.to_string(),
schema: Some(root_id.to_string()),
..Default::default()
}
});
return;
}
let mut target_id = c.obj.id.clone();
if target_id.is_none() {
for (i, c) in one_of.iter().enumerate() {
let mut child_id = String::new();
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &c.obj.type_ {
if !crate::database::object::is_primitive_type(t) {
target_id = Some(t.clone());
child_id = t.clone();
}
}
}
if let Some(tid) = target_id {
options.insert(val, tid);
if let Some(val) = c.obj.get_discriminator_value(&strategy, &child_id) {
if options.contains_key(&val) {
errors.push(crate::drop::Error {
code: "POLYMORPHIC_COLLISION".to_string(),
message: format!("Polymorphic boundary defines multiple candidates mapped to the identical discriminator value '{}'.", val),
details: crate::drop::ErrorDetails {
path: path.to_string(),
schema: Some(root_id.to_string()),
..Default::default()
}
});
continue;
}
options.insert(val, (Some(i), None));
}
}
}
}
} else {
return;
}
if !options.is_empty() {
let _ = self.obj.compiled_discriminator.set(strategy);
if !strategy.is_empty() {
let _ = self.obj.compiled_discriminator.set(strategy);
}
let _ = self.obj.compiled_options.set(options);
}
}
#[allow(unused_variables)]
fn validate_identifier(id: &str, field_name: &str, errors: &mut Vec<crate::drop::Error>) {
fn validate_identifier(
id: &str,
field_name: &str,
root_id: &str,
path: &str,
errors: &mut Vec<crate::drop::Error>,
) {
#[cfg(not(test))]
for c in id.chars() {
if !c.is_ascii_lowercase() && !c.is_ascii_digit() && c != '_' && c != '.' {
@ -401,9 +488,13 @@ impl Schema {
code: "INVALID_IDENTIFIER".to_string(),
message: format!(
"Invalid character '{}' in JSON Schema '{}' property: '{}'. Identifiers must exclusively contain [a-z0-9_.]",
c, field_name, id
c, field_name, id
),
details: crate::drop::ErrorDetails::default(),
details: crate::drop::ErrorDetails {
path: path.to_string(),
schema: Some(root_id.to_string()),
..Default::default()
},
});
return;
}
@ -411,116 +502,124 @@ impl Schema {
}
pub fn collect_schemas(
&mut self,
tracking_path: Option<String>,
to_insert: &mut Vec<(String, Schema)>,
schema_arc: &Arc<Schema>,
root_id: &str,
path: String,
to_insert: &mut Vec<(String, Arc<Schema>)>,
errors: &mut Vec<crate::drop::Error>,
) {
if let Some(id) = &self.obj.id {
Self::validate_identifier(id, "$id", errors);
to_insert.push((id.clone(), self.clone()));
let mut should_push = false;
// Push ad-hoc inline composition into the addressable registry
if schema_arc.obj.properties.is_some()
|| schema_arc.obj.items.is_some()
|| schema_arc.obj.family.is_some()
|| schema_arc.obj.one_of.is_some()
{
should_push = true;
}
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &self.obj.type_ {
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &schema_arc.obj.type_ {
if !crate::database::object::is_primitive_type(t) {
Self::validate_identifier(t, "type", errors);
}
}
if let Some(family) = &self.obj.family {
Self::validate_identifier(family, "$family", errors);
}
// Is this schema an inline ad-hoc composition?
// Meaning it has a tracking context, lacks an explicit $id, but extends an Entity ref with explicit properties!
if self.obj.id.is_none() && self.obj.properties.is_some() {
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &self.obj.type_ {
if !crate::database::object::is_primitive_type(t) {
if let Some(ref path) = tracking_path {
to_insert.push((path.clone(), self.clone()));
}
}
Self::validate_identifier(t, "type", root_id, &path, errors);
should_push = true;
}
}
// Provide the path origin to children natively, prioritizing the explicit `$id` boundary if one exists
let origin_path = self.obj.id.clone().or(tracking_path);
if let Some(family) = &schema_arc.obj.family {
Self::validate_identifier(family, "$family", root_id, &path, errors);
}
self.collect_child_schemas(origin_path, to_insert, errors);
if should_push {
to_insert.push((path.clone(), Arc::clone(schema_arc)));
}
Self::collect_child_schemas(schema_arc, root_id, path, to_insert, errors);
}
pub fn collect_child_schemas(
&mut self,
origin_path: Option<String>,
to_insert: &mut Vec<(String, Schema)>,
schema_arc: &Arc<Schema>,
root_id: &str,
path: String,
to_insert: &mut Vec<(String, Arc<Schema>)>,
errors: &mut Vec<crate::drop::Error>,
) {
if let Some(props) = &mut self.obj.properties {
for (k, v) in props.iter_mut() {
let mut inner = (**v).clone();
let next_path = origin_path.as_ref().map(|o| format!("{}/{}", o, k));
inner.collect_schemas(next_path, to_insert, errors);
*v = Arc::new(inner);
if let Some(props) = &schema_arc.obj.properties {
for (k, v) in props.iter() {
let next_path = format!("{}/{}", path, k);
Self::collect_schemas(v, root_id, next_path, to_insert, errors);
}
}
if let Some(pattern_props) = &mut self.obj.pattern_properties {
for (k, v) in pattern_props.iter_mut() {
let mut inner = (**v).clone();
let next_path = origin_path.as_ref().map(|o| format!("{}/{}", o, k));
inner.collect_schemas(next_path, to_insert, errors);
*v = Arc::new(inner);
if let Some(pattern_props) = &schema_arc.obj.pattern_properties {
for (k, v) in pattern_props.iter() {
let next_path = format!("{}/{}", path, k);
Self::collect_schemas(v, root_id, next_path, to_insert, errors);
}
}
let mut map_arr = |arr: &mut Vec<Arc<Schema>>| {
for v in arr.iter_mut() {
let mut inner = (**v).clone();
inner.collect_schemas(origin_path.clone(), to_insert, errors);
*v = Arc::new(inner);
let mut map_arr = |arr: &Vec<Arc<Schema>>, sub: &str| {
for (i, v) in arr.iter().enumerate() {
Self::collect_schemas(v, root_id, format!("{}/{}/{}", path, sub, i), to_insert, errors);
}
};
if let Some(arr) = &mut self.obj.prefix_items {
map_arr(arr);
if let Some(arr) = &schema_arc.obj.prefix_items {
map_arr(arr, "prefixItems");
}
if let Some(arr) = &mut self.obj.one_of {
map_arr(arr);
if let Some(arr) = &schema_arc.obj.one_of {
map_arr(arr, "oneOf");
}
let mut map_opt = |opt: &mut Option<Arc<Schema>>, pass_path: bool| {
let mut map_opt = |opt: &Option<Arc<Schema>>, pass_path: bool, sub: &str| {
if let Some(v) = opt {
let mut inner = (**v).clone();
let next = if pass_path { origin_path.clone() } else { None };
inner.collect_schemas(next, to_insert, errors);
*v = Arc::new(inner);
if pass_path {
Self::collect_schemas(v, root_id, format!("{}/{}", path, sub), to_insert, errors);
} else {
Self::collect_child_schemas(v, root_id, format!("{}/{}", path, sub), to_insert, errors);
}
}
};
map_opt(&mut self.obj.additional_properties, false);
map_opt(
&schema_arc.obj.additional_properties,
false,
"additionalProperties",
);
map_opt(&schema_arc.obj.items, true, "items");
map_opt(&schema_arc.obj.not, false, "not");
map_opt(&schema_arc.obj.contains, false, "contains");
map_opt(&schema_arc.obj.property_names, false, "propertyNames");
// `items` absolutely must inherit the EXACT property path assigned to the Array wrapper!
// This allows nested Arrays enclosing bare Entity structs to correctly register as the boundary mapping.
map_opt(&mut self.obj.items, true);
map_opt(&mut self.obj.not, false);
map_opt(&mut self.obj.contains, false);
map_opt(&mut self.obj.property_names, false);
if let Some(cases) = &mut self.obj.cases {
for c in cases.iter_mut() {
if let Some(when) = &mut c.when {
let mut inner = (**when).clone();
inner.collect_schemas(origin_path.clone(), to_insert, errors);
*when = Arc::new(inner);
if let Some(cases) = &schema_arc.obj.cases {
for (i, c) in cases.iter().enumerate() {
if let Some(when) = &c.when {
Self::collect_schemas(
when,
root_id,
format!("{}/cases/{}/when", path, i),
to_insert,
errors,
);
}
if let Some(then) = &mut c.then {
let mut inner = (**then).clone();
inner.collect_schemas(origin_path.clone(), to_insert, errors);
*then = Arc::new(inner);
if let Some(then) = &c.then {
Self::collect_schemas(
then,
root_id,
format!("{}/cases/{}/then", path, i),
to_insert,
errors,
);
}
if let Some(else_) = &mut c.else_ {
let mut inner = (**else_).clone();
inner.collect_schemas(origin_path.clone(), to_insert, errors);
*else_ = Arc::new(inner);
if let Some(else_) = &c.else_ {
Self::collect_schemas(
else_,
root_id,
format!("{}/cases/{}/else", path, i),
to_insert,
errors,
);
}
}
}