///|
/// Build a snapshot from supported raw-MRI paths and complete JSON sources.
/// Repeated paths, scope errors, duplicate JSON keys and unknown profiles fail.
pub fn DatasetIndex::from_manifest(
files : Array[String],
sidecars : Array[SidecarInput],
) -> DatasetIndex raise TraceError {
let paths : Map[String, String] = Map([])
let labels : Map[String, String] = Map([])
fn register(item : Selector) -> Unit raise TraceError {
let folded = item.path.to_lower()
if paths.get(folded) is Some(existing) {
reject(
"path_collision",
item.path,
"Duplicate or case-colliding path; supply each source once.",
related=[existing],
)
}
paths[folded] = item.path
for key, value in item.entities {
let folded_label = key + ":" + value.to_lower()
if labels.get(folded_label) is Some(existing) && existing != value {
reject(
"label_collision",
item.path,
"Entity labels collide when case is ignored: " +
existing +
" / " +
value,
)
}
labels[folded_label] = value
}
}
let data = files.map(path => {
let item = selector(path, sidecar=false)
register(item)
item
})
let metadata = sidecars.map(input => {
let item = selector(input.path, sidecar=true)
register(item)
guard parse_source(input.path, input.text) is Object(fields) else {
reject(
"expected_object",
input.path,
"A JSON sidecar must contain an object at the top level.",
)
return { selector: item, metadata: Map([]), }
}
{ selector: item, metadata: fields, }
})
data.sort_by((a, b) => lexical_compare(a.path, b.path))
metadata.sort_by((a, b) => {
let depth = a.selector.depth.compare(b.selector.depth)
if depth == 0 {
lexical_compare(a.selector.path, b.selector.path)
} else {
depth
}
})
let file_positions : Map[String, Int32] = Map([])
for position, file in data {
file_positions[file.path] = position
}
let index : DatasetIndex = {
files: data,
sidecars: metadata,
file_positions,
source_buckets: make_source_buckets(metadata),
}
// Every accepted snapshot must be reloadable through the same public API.
if index.to_manifest_json().length() > 2097152 {
reject(
"snapshot_limit", "", "Canonical snapshot exceeds 2,097,152 UTF-16 code units; split the snapshot before constructing an index.",
)
}
index
}
///|
pub fn DatasetIndex::data_paths(self : DatasetIndex) -> Array[String] {
self.files.map(file => file.path)
}
///|
/// Resolve JSON top-level assignments only. Same-level ambiguity is an error,
/// even when one filename has more entities or the values happen to agree.
pub fn DatasetIndex::resolve(
self : DatasetIndex,
data_path : String,
) -> ResolvedMetadata raise TraceError {
guard self.file_positions.get(data_path) is Some(index) else {
reject(
"unknown_data_path", data_path, "Data path is absent from the manifest; add it before querying.",
)
return { path: data_path, values: Map([]), origins: Map([]), applied: [], }
}
let data = self.files[index]
let candidates = self.matching_sources(data)
resolve_candidates(data_path, candidates)
}
///|
fn resolve_candidates(
data_path : String,
candidates : Array[Sidecar],
) -> ResolvedMetadata raise TraceError {
let at_depth : Map[Int32, Array[String]] = Map([])
for sidecar in candidates {
let level = sidecar.selector.depth
let paths = at_depth.get_or_init(level, () => [])
paths.push(sidecar.selector.path)
}
for sidecar in candidates {
let paths = at_depth[sidecar.selector.depth]
if paths.length() > 1 {
reject(
"ambiguous_inheritance",
data_path,
"Multiple JSON sidecars apply at the same directory level; consolidate them rather than relying on filename specificity.",
related=paths.copy(),
)
}
}
let values : Map[String, Json] = Map([])
let origins : Map[String, Array[FieldOrigin]] = Map([])
let applied : Array[String] = []
for sidecar in candidates {
applied.push(sidecar.selector.path)
for key in sorted_keys(sidecar.metadata) {
let value = copy_json(sidecar.metadata[key])
values[key] = value
origins
.get_or_init(key, () => [])
.push({ path: sidecar.selector.path, value, })
}
}
{ path: data_path, values, origins, applied, }
}