(feat): Generate interfaces for WebSocket API classes (e.g., IStreamApi, ITranscribeApi)
to improve testability. Each WebSocket client now implements a corresponding interface
that declares all public event properties, Status, ConnectAsync, Send, and
CloseAsync. The root client interface (ICortiClient) also includes factory method
signatures (CreateStreamApi, CreateTranscribeApi) when WebSockets are enabled.
(fix): Fix Event<T> thread-safety issue. RaiseEvent now snapshots the subscriber
collections under a lock before iterating, and Subscribe, Unsubscribe, and
UnsubscribeAll are synchronized to prevent InvalidOperationException when
handlers are added or removed concurrently from different threads.
(feat): Add optional CancellationToken parameter to all public async WebSocket methods
(ConnectAsync, CloseAsync, and Send overloads). The token is threaded through
the internal WebSocketClient, WebSocketConnection, and down to the underlying
ClientWebSocket.SendAsync/ConnectAsync/CloseAsync calls, enabling callers to
cancel long-running WebSocket operations.
(fix): Fix WebSocket binary messages being sent with WebSocketMessageType.Text instead of
WebSocketMessageType.Binary. RequestBinaryMessage and RequestBinarySegmentMessage
now correctly use WebSocketMessageType.Binary when calling SendAsync, ensuring
audio data (e.g. webm/opus chunks) is sent as binary frames.
(fix): Add ReadAsPropertyName and WriteAsPropertyName overrides to all remaining
custom JsonConverter types: EnumSerializer<TEnum> (native C# enums),
DateTimeSerializer, DateAsDateTimeConverter, discriminated union converters,
and literal type converters. Without these overrides, System.Text.Json throws
NotSupportedException when any of these types is used as a Dictionary<TKey, TValue>
key. This complements the IStringEnum fix in 2.35.1.
(feat): Replace separate deserialization and serialization tests with a single round-trip
serialization test using JsonAssert.Roundtrips<T>(inputJson). The helper deserializes
JSON to T, re-serializes, and compares to the original JSON via JsonElement deep
equality, producing diff-reportable failures.
(feat): Add UsingObjectDictionaryComparer to test comparers for handling
Dictionary<string, object?> fields. System.Text.Json deserializes
object? values as JsonElement, so structural equality comparisons
need to serialize both sides before comparing. The UsingDefaults()
chain now includes this comparer automatically.
(fix): Add ReadAsPropertyName and WriteAsPropertyName overrides to the generated
IStringEnum JsonConverter. Without these overrides, System.Text.Json throws
NotSupportedException at runtime when serializing or deserializing a
Dictionary<TStringEnum, TValue>. This is applied to all generated IStringEnum
types so dictionary-key usage works without requiring regeneration.
(fix): Fix WebSocket binary message sending. Binary messages (e.g. audio bytes) are now
sent as raw bytes instead of being JSON-serialized, which caused servers to reject
them with CONFIG_DENIED.
(fix): Fix WebSocket incoming message deserialization. TryDeserialize now passes
JsonSerializerOptions so the generated literal property setters correctly
validate const discriminator fields (e.g. type: "transcript" vs type: "flushed")
during deserialization.
(feat): Add forward-compatible UnknownMessage event to WebSocket clients. When the server
sends an event type not recognized by the SDK, it is now dispatched to the
UnknownMessage event handler (as a JsonElement) instead of raising an exception.
This allows SDKs to gracefully handle new server event types without requiring
regeneration.