///|
using @jsonrpc {
type RequestId,
type JsonRpcId,
type JsonRpcRequest,
type JsonRpcNotification,
type JsonRpcResponse,
type JsonRpcError,
type JsonRpcMessage,
}
///|
/// The lifecycle of a pure connection reducer.
enum ConnectionPhase {
ConnectionOpen
ConnectionClosed(reason~ : String)
} derive(Eq, Debug)
///|
/// A request initiated by the local endpoint and awaiting its peer.
struct PendingOutbound {
id : RequestId
method_name : String
cancel_requested : Bool
} derive(Eq, Debug)
///|
/// A request initiated by the peer and awaiting local handler completion.
struct PendingInbound {
id : RequestId
method_name : String
cancel_requested : Bool
} derive(Eq, Debug)
///|
/// All mutable-looking connection data is carried explicitly in this value.
/// The reducer never mutates an input state's arrays; each transition copies
/// and updates its own arrays before returning a new state.
struct ConnectionState {
phase : ConnectionPhase
outbound : Array[PendingOutbound]
inbound : Array[PendingInbound]
settled_outbound : Array[RequestId]
settled_inbound : Array[RequestId]
} derive(Eq, Debug)
///|
/// The initial open state.
#warnings("-unused_value")
fn connection_state() -> ConnectionState {
{
phase: ConnectionOpen,
outbound: [],
inbound: [],
settled_outbound: [],
settled_inbound: [],
}
}
///|
/// Events are data only. Effects are represented by `ConnectionCommand` in
/// the reducer output and are interpreted by a runtime outside this package.
#warnings("-unused_constructor")
enum ConnectionEvent {
OutgoingRequest(JsonRpcRequest)
OutgoingNotification(JsonRpcNotification)
IncomingRequest(JsonRpcRequest)
IncomingNotification(JsonRpcNotification)
IncomingResponse(JsonRpcResponse)
IncomingCompleted(id~ : RequestId, result~ : Json)
IncomingFailed(id~ : RequestId, error~ : JsonRpcError)
CancelOutbound(id~ : RequestId)
CancelInbound(id~ : RequestId)
Close(reason~ : String)
Eof
} derive(Eq, Debug)
///|
/// The precise, closed reason set for one tolerated inbound wire
/// cancellation. An ACP `$/cancel_request` is best-effort by wire contract:
/// the receiver MAY cancel the matching activity, the only obligation is
/// that the original request still receives its response, and the contract
/// is silent on ids that were never seen or already settled. Real ACP
/// clients routinely send cancels that lose the race with an
/// already-delivered response, so every well-formed cancel of a non-live id
/// is a traced no-op instead of a connection failure.
enum ConnectionCancelIgnoreReason {
CancelUnknownRequest
CancelAlreadySettled
CancelAlreadyCancelled
} derive(Eq, Debug)
///|
/// Intent-only commands. No command owns an async task, queue, callback, or
/// dependency environment.
enum ConnectionCommand {
WriteMessage(JsonRpcMessage)
DispatchRequest(JsonRpcRequest)
DispatchNotification(JsonRpcNotification)
CompleteOutbound(id~ : RequestId, response~ : JsonRpcResponse)
FailOutbound(id~ : RequestId, reason~ : String)
FailInbound(id~ : RequestId, reason~ : String, cancelled~ : Bool)
CancelOutboundTask(id~ : RequestId)
CancelInboundTask(id~ : RequestId)
Trace(message~ : String)
/// A tolerated inbound wire cancellation of a non-live id. This is a
/// trace-only intent: no response, no state change, no native cancel.
TraceCancelIgnored(id~ : RequestId, reason~ : ConnectionCancelIgnoreReason)
} derive(Eq, Debug)
///|
/// A pure transition result.
struct ConnectionStep {
state : ConnectionState
commands : Array[ConnectionCommand]
} derive(Eq, Debug)
///|
/// Reducer failures are structured and never converted into silent defaults.
suberror ConnectionError {
Closed(reason~ : String)
AlreadyClosed(reason~ : String)
DuplicateOutbound(id~ : RequestId)
DuplicateInbound(id~ : RequestId)
UnknownResponse(id~ : RequestId)
DuplicateResponse(id~ : RequestId)
LateResponse(id~ : RequestId)
InvalidCancellation(reason~ : String)
UnknownCancellation(id~ : RequestId)
DuplicateCancellation(id~ : RequestId)
UnknownInboundCompletion(id~ : RequestId)
LateInboundCompletion(id~ : RequestId)
} derive(Eq, Debug)