Release 6th November 2025
Change Control note Hiperspace --version 2.5.2 HiLang --version 2.5.2
Overview
This release builds on the HiperEdge functionality provided by message to execute queries on a remote Hiperspace.DB and return the full set of elements back to a client without the need to return every intermediate object necessary. The prime example is the Hiperspace.DB opening page, which displays a summary bar-graphs of the number of nodes and edges in each database, and validates that changes to the (compiled) schema for databases does not change the definition of an already stored element set.
The graph-view functionality of Hiperspace.DB uses HiperEdge functions to recursively search (in parallel) all Node types that satisfy the view criteria and display as a navigable SVG graph of connections. These capabilities use the GraphFunctions to search Nodes using message-keys sent to the server and message-value provided on completion together with rendering information for Node shapes and color.
To support these use-cases, a couple of enhancements have been added to Hiperspace and HiLang to better support the functions.
SubSpace
IServiceProvider is an interface on the .NET Platform to inject Services into components (IoC) at runtime. A ServiceProvider property has been added to SubSpace to enable messages to enlist functionality when a message is received, and a parameter added to SubSpaceParameters for domain space construction.
FindPaths and FindPathsAsync functions now have domain-specific implementations that use a message to transmit the call through to a server where the parallel recursive search can be efficiently executed close the data, using many of the cores of the server.
Node
The Node element has been extended to include additional functions that provide HiperEdge search for related nodes across transitive edges
| │ | Name | │ | Description | │ |
|---|---|---|---|---|
| + | ━━━━━━━━ | + | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | + |
| │ | HiperEdges | │ | Treat the TypeName parameter as a HiperEdge and find all matching | │ |
| │ | HiperEdgesAsync | │ | as above, but non-blocking (especially for Blazor web clients) | │ |
/// <summary>
/// Treat the Edges of TypeName as a HiperEdge and find all transitive paths for that type
/// </summary>
/// <param name="TypeName">The Edge type name</param>
/// <param name="length">the maximum length of the path</param>
/// <param name="targets">only return HiperEdges that end with a Node of the type matching one of these types</param>
/// <returns>The full set of HiperEdges for this path</returns>
public HashSet<HiperEdge> HiperEdges(string TypeName, int? length = null, HashSet<string>? targets = null)
/// <summary>
/// Create an inline HiperName from TypeNames and find all transitive paths for that type
/// </summary>
/// <param name="HiperName">The name of the HiperEdge being infered from the Edge TyopeNames</param>
/// <param name="TypeNames">the set of Edge TypeNames that make up this HiperEdge</param>
/// <param name="length">the maximum length of the path</param>
/// <param name="targets">only return HiperEdges that end with a Node of the type matching one of these types</param>
/// <returns>The full set of HiperEdges for this path</returns>
public HashSet<HiperEdge> HiperEdges(string HiperName, IEnumerable<string> TypeNames, int? length = null, HashSet<string>? targets = null)
/// <summary>
/// Treat the Edges of TypeName as a HiperEdge and find all transitive paths for that type
/// </summary>
/// <param name="TypeName">the name given to this transitative hiperedge</param>
/// <param name="rules">the set of meta edges (start-node type, end-node type, edge type) rules that define the transitative path</param>
/// <param name="length">the maximum length of the path</param>
/// <param name="targets">only return HiperEdges that end with a Node of the type matching one of these types</param>
/// <returns>The full set of HiperEdges for this path</returns>
public HashSet<HiperEdge> HiperEdges(string TypeName, HashSet<Rule> rules, int? length = null, HashSet<string>? targets = null)
/// <summary>
/// Treat the Edges of TypeName as a HiperEdge and find all transitive paths for that type
/// </summary>
/// <param name="TypeName">The Edge type name</param>
/// <param name="length">the maximum length of the path</param>
/// <param name="targets">only return HiperEdges that end with a Node of the type matching one of these types</param>
/// <returns>The full set of HiperEdges for this path</returns>
public async Task<HashSet<Graph.HiperEdge>> HiperEdgesAsync(string TypeName, int? length = null, HashSet<string>? targets = null, CancellationToken cancellationToken = default)
/// <summary>
/// Create an inline HiperName from TypeNames and find all transitive paths for that type
/// </summary>
/// <param name="HiperName">The name of the HiperEdge being infered from the Edge TyopeNames</param>
/// <param name="TypeNames">the set of Edge TypeNames that make up this HiperEdge</param>
/// <param name="length">the maximum length of the path</param>
/// <param name="targets">only return HiperEdges that end with a Node of the type matching one of these types</param>
/// <returns>The full set of HiperEdges for this path</returns>
public async Task<HashSet<HiperEdge>> HiperEdgesAsync(string HiperName, IEnumerable<string> TypeNames, int? length = null, HashSet<string>? targets = null, CancellationToken cancellationToken = default)
/// <summary>
/// Treat the Edges of TypeName as a HiperEdge and find all transitive paths for that type
/// </summary>
/// <param name="TypeName">the name given to this transitative hiperedge</param>
/// <param name="rules">the set of meta edges (start-node type, end-node type, edge type) rules that define the transitative path</param>
/// <param name="length">the maximum length of the path</param>
/// <param name="targets">only return HiperEdges that end with a Node of the type matching one of these types</param>
/// <returns>The full set of HiperEdges for this path</returns>
public async Task<HashSet<Graph.HiperEdge>> HiperEdgesAsync(string TypeName, HashSet<Rule> rules, int? length = null, HashSet<string>? targets = null, CancellationToken cancellationToken = default)
The Test cases demonstrate the use of these functions to provide server-side search for relations. The first example treats "Child" as a transitive HiperEdge, while the second infers an "Ancestors" HiperEdge from either Mother or Father.
var descendants = node.HiperEdges("Child");
var ancestors = node.HiperEdges("Ancestors", new[] {"Mother", "Father" });
Release 6th November 2025
Release 23rd October 2025
Release 20th October 2025