Files
esiur-dotnet/Tools/Esiur.CLI/ARCHITECTURE.md
T
2026-07-18 00:44:14 +03:00

63 lines
5.8 KiB
Markdown

# CLI repository analysis
This report records the analysis performed before the cross-platform CLI foundation was implemented.
## Reusable Esiur.Net APIs
- `Warehouse.Get<EpConnection>(endpoint, EpConnectionContext)` parses `ep://` URLs, creates the protocol store, opens the connection, and performs authentication.
- `EpConnectionContext` selects authentication mode, provider protocol, identity, domain, reconnect behavior, and authentication timeout.
- `PasswordAuthenticationProvider` and its handler implement the current `password-sha3-v1` exchange. The provider obtains client credentials through `GetSelfCredential` or `GetSelfIdentityAndCredential`. The exchange does not expose a reusable login token.
- `EpConnection.Get(path)` resolves and attaches one stable resource path. `EpConnection.Query(path)` queries children, and `EpConnection.GetLinkDefinitions(path)` obtains reachable remote definitions.
- `EpResource` contains the peer's session-local resource ID and stable link, its attached property snapshot, and the remote definition installed on `Instance.Definition`.
- `TypeDef`, `PropertyDef`, `FunctionDef`, `EventDef`, `ConstantDef`, and `ArgumentDef` expose names, member indexes, inheritance, annotations, flags, and TRU type descriptors.
- `EpResource.TryGetPropertyValue(index, out value)` reads the attached property cache without generated stubs. Dynamic invocation and subscriptions are available through `_Invoke`, `_InvokeStream`, `Subscribe`, and `Unsubscribe` for later phases.
- `Warehouse.Close` and `EpConnection.Destroy` provide deterministic one-shot cleanup.
Esiur.Net currently represents type identity as an unsigned 64-bit ID, not `System.Guid`. The CLI renders this losslessly as a 16-digit hexadecimal value.
## Existing C# generators
Two generators have distinct roles:
- `Libraries/Esiur/Proxy/ResourceGenerator.cs` is the incremental compile-time source generator for locally attributed resources.
- `Libraries/Esiur/Proxy/TypeDefGenerator.cs` consumes remote definitions and emits C# proxies, records, enums, and registration code.
`TypeDefGenerator` is the later CLI generation reference. It emits `EpResource` subclasses, preserves member indexes, attaches remote instances using connection/instance ID/age/link constructors, maps TRUs including nullable and composite types, carries annotations and remote names, handles inheritance, and emits record, enum, static-call, event, and streaming shapes. It should be refactored behind the future `ICodeGenerator` abstraction rather than replaced.
## Relevant esiur-ts APIs
The TypeScript v3 runtime already provides:
- `EpConnection.get`, resource attachment, indexed `invoke` and `set`, remote TypeDef fetching, and property/event notification handling.
- `EpResource` with a property cache, type definition, dynamic proxy access, and property/event notification sources.
- `RemoteTypeDef` decoding with remote property, function, event, constant, flag, annotation, and TRU metadata.
- resource decorators and `TypeDef` templates, warehouse type registration, record classes, enum wrappers, and list/map/nullable TRU descriptors.
- `bigint`-capable integer codecs and typed wire descriptors needed to avoid mapping 64-bit integers to JavaScript `number`.
Generated TypeScript stubs still need a public generated-resource base or factory, stable static type metadata and UUID/ID registration, typed indexed property/function/event wrappers, an inheritance metadata convention, and a documented generated record/enum registration shape. Those changes belong to the TypeScript generation phase and were not made here.
## Browsing gaps and changes
The protocol already supports the first-phase operations, so the CLI does not parse EP packets. `AsyncReply` has no `CancellationToken` overload; the CLI adapts it to a task and disposes the connection when cancellation or timeout ends the operation. Native cancellation-aware library overloads remain a useful future addition.
Testing exposed one reusable browsing defect: `MemoryStore.Children` returned no children for a root store and returned all descendants for a non-root resource. It now returns true direct children, including at the store root, and honors the optional child name filter. This makes remote `query` traversal consistent and lets recursion remain an application-level policy.
The protocol query reply does not carry child counts, so the CLI obtains each displayed direct child count with an additional query. A richer batched browsing API may be worthwhile for high-latency servers.
## CLI structure
- `Configuration`: JSON configuration, named profiles, endpoint validation, duration parsing, and precedence resolution.
- `Authentication`: a replaceable credential service. The default implementation prompts or reads explicit standard input and persists nothing.
- `Client`: session creation/disposal and reusable resource inspection services.
- `Rendering`: table, JSON, JSON Lines, raw output, TRU formatting, and safe value normalization.
- `CliApplication`: parsing and dispatch only; protocol operations remain in services shared by future shell commands.
- `Tests/Esiur.CLI.Tests`: unit tests plus an in-process Esiur server integration test.
## Compatibility risks
- Password profiles require another prompt because the current authentication provider does not return a reusable token and the foundation intentionally adds no platform-specific secret-store dependency.
- Recursive queries require multiple network round trips; child counts add another query per result.
- Session IDs are peer-local and cannot be reused by another CLI process.
- Type identity is currently `ulong`; output consumers must not assume a GUID string.
- Trimming and NativeAOT remain disabled because dynamic resource attachment, reflection, and serialization have not been validated under those deployment modes.