using ZB.MOM.WW.OtOpcUa.Core.Abstractions; namespace ZB.MOM.WW.OtOpcUa.Commons.Browsing; /// One node captured from a driver's DiscoverAsync stream. Folder ids are /// path-composed ("/parent/child"); leaf ids are the driver FullName (the commit value). public sealed class CapturedNode { /// Stable identifier. Folder = path-composed ("/parent/child"); leaf = driver FullName. public required string Id { get; init; } /// Browse name (the path segment under the parent). public required string Name { get; init; } /// Human-readable display name. public required string DisplayName { get; init; } /// True for a variable (terminal); false for a folder. public required bool IsLeaf { get; init; } /// Driver-side attribute metadata; set only on leaves. public DriverAttributeInfo? Attribute { get; init; } /// True when the driver marked this leaf as an alarm condition during discovery. public bool IsAlarmMarked { get; set; } /// Captured child nodes (folders first-or-interleaved in stream order). public List Children { get; } = []; /// Captured static properties attached to this node via AddProperty. public List<(string Name, DriverDataType Type, object? Value)> Properties { get; } = []; } /// Immutable-after-Build snapshot of a whole discovery capture. May be shared by /// multiple coalesced browse sessions — sessions drop their reference on dispose, never mutate. public sealed class CapturedTree { /// Synthetic root; its Children are the top-level captured nodes. public required CapturedNode Root { get; init; } /// True when the node cap was hit and recording stopped short. public required bool Truncated { get; init; } /// Number of nodes actually recorded (bounded by the node cap). public required int Count { get; init; } /// Flat lookup from node id to node (for O(1) Expand/Attributes serving). public required IReadOnlyDictionary ById { get; init; } }