iwe
Added
--filterrelational operators gain a$sizecount predicate —--filter '$includedBy: { $size: 0 }'finds roots,--filter '$includes: { $size: 0 }'finds leaves,--filter '$referencedBy: { $size: { $gte: 5 } }'finds hubs.
Changed
--filterrelational operators default to direct edges (maxDepth/maxDistance1) when the bound is omitted; an unbounded walk is now spelledmaxDepth: 0/maxDistance: 0(was: omitting the bound meant unbounded). The structural anchor flags are unaffected —--included-by KEYwas already direct and--included-by KEY:0is still unbounded.
iwec
Added
iwe_queryrelational operators gain a$sizecount predicate —$includedBy: { $size: 0 }(roots),$includes: { $size: 0 }(leaves),$referencedBy: { $size: { $gte: 5 } }(hubs). Takes a non-negative integer or a mapping of$eq/$ne/$gt/$gte/$lt/$ltecomparisons.
Changed
iwe_queryrelational operators default to direct edges whenmaxDepth/maxDistanceis omitted; an unbounded walk is now spelledmaxDepth: 0/maxDistance: 0(was unbounded by default).matchis now optional, defaulting to any document.
liwe
Added
$sizecardinality predicate on the relational operators ($includes,$includedBy,$references,$referencedBy) — count the distinct related documents instead of testing for existence, e.g.$includedBy: { $size: 0 }(roots),$referencedBy: { $size: { $gte: 5 } }(hubs). Takes a non-negative integer or a mapping of$eq/$ne/$gt/$gte/$lt/$ltecomparisons;CountPred/CountCmpare the new public types andInclusionAnchor/ReferenceAnchorgain asize: Option<CountPred>field.- The frontmatter array
$sizeoperator now accepts count comparisons ({ $size: { $gte: 3 } }) in addition to an exact integer;FieldOp::Sizecarries aCountPred(wasu64). model::ids—alloc_node_id/alloc_line_idback every id from a single process-global atomic counter (starting at 1), so ids are unique for the process lifetime and never re-issued;Idsis the handle type.Tree.line_range: Option<LineRange>— the source line range a tree node was read from, populated when a tree is collected from the graph and preserved across an export/import round-trip.NodeIter::iter_id()andNodeIter::line_range()— a node's id and source line range while iterating;GraphBuilder::insert_from_iterstores each imported node underiter_id()(honoring caller-provided ids instead of allocating fresh ones) and returns the accumulatedNodesMap.
Changed
- Relational operators in the mapping form default
maxDepth/maxDistanceto direct edges (was: absence meant an unbounded walk);maxDepth: 0/maxDistance: 0is the new unbounded sentinel.matchis now optional and defaults to any document, soInclusionAnchor::with_match(Filter::all(), ..)-style anchors are expressible from the query language directly. NodeIdandLineIdare nowi64(wereu64andusize).Tree.idis now a mandatoryNodeId(wasOption<NodeId>); synthesized tree nodes receive a fresh id.Tree::newtakes aNodeIdin place of anOption<NodeId>.Treeequality is structural — it comparesnodeandchildrenand ignoresidandline_range, so two independently built trees of the same content are equal.Graphequality likewise compares the per-key exported trees rather than raw arena positions.- The arena stores nodes and lines in hash maps, so a dangling id resolves to
GraphNode::Emptyinstead of panicking and deleted ids are dropped rather than recycled. Graph::nodes()is replaced bynode_count(),node_ids(), andsection_ids()— the old accessor returned the backingVec<GraphNode>, which no longer exists; callers that only need a count or a set of ids avoid materializing every node.Graph::get_lineandArena::get_linereturn&Line(was an ownedLine), so reading a line no longer clones its inlines on every access.