All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project follows Semantic Versioning once stable releases start.
- Added
OscServer.serve()as the recommended standalone server startup API. - Added
OscServer.join()for waiting until a server has fully stopped without initiating shutdown. - Added
OscServer.stop(gracePeriod)andOscServer.stopAsync(gracePeriod)for graceful server shutdown windows.
- Documented
OscServershutdown semantics, including first-call-winsstopAsyncbehavior and the effect of non-cancellable route handlers.
- Added
oscMessageOf(address, vararg args)for buildingOscMessagevalues from regular Kotlin values. - Added
buildOscBundle(timetag) { ... }as the bundle DSL entry point. - Added
OscBundleBuilder.packet(packet)for adding prebuilt messages or nested bundles to a bundle DSL block.
OscBundleBuilder.messagenow has a singlemessage(address, vararg args: Any?)form and uses the same boxing rules asoscMessageOf.ListandArrayvalues passed tooscMessageOfor bundlemessageare treated as one OSC array argument. Spread a collection explicitly when passing it as multiple message arguments.OscServerBackendis now one-shot, and itsreceivedPacketsflow closes whenOscServerBackend.stop()completes.
- Fixed an intermittent
TcpOscServerBackend.stop()failure caused by snapshotting active TCP clients while client read loops were removing themselves concurrently.
- Removed the
OscMessagecompanioninvokehelpers for user-value construction. - Removed the old
oscBundlebundle DSL entry point. - Removed the
OscBundleBuilder.messageoverloads that acceptedList<OscArg>,List<Any?>, orvararg OscArg.
// Before
val message = OscMessage("/path", 1, "x")
val bundle = oscBundle {
message("/a", listOf(1, 2))
}
// After
val message = oscMessageOf("/path", 1, "x")
val bundle = buildOscBundle {
message("/a", listOf(1, 2)) // one OscArray argument
}
// To pass a collection as multiple message arguments:
val args = listOf(1, 2)
val expanded = oscMessageOf("/a", *args.toTypedArray())- Added TCP client/server transport support through
OscTransportProtocol.Tcp. - Added TCP packet framing strategies:
OscTcpFramingStrategy.LENGTH_PREFIXEDandOscTcpFramingStrategy.SLIP. - Added client/server DSL transport selection:
protocol { udp() }protocol { tcp() }protocol { tcp { framingStrategy = OscTcpFramingStrategy.SLIP } }
- Added TCP backend tests and public API round-trip coverage for default length-prefixed framing and SLIP framing.
OscClientno longer accepts an external coroutine scope. Client shutdown is managed internally throughcloseAsync(),closeAndJoin(), andclose().OscServercan now be configured with UDP or TCP transport while keeping UDP as the default.
- Removed
scopefromOscClientandOscClientOptionsBuilder.
// Before
val client = OscClient(address, scope)
// After
val client = OscClient(address)- Runnable examples under
examples/, including codec, bundle DSL, UDP client/server, routing, and scheduling use cases.
- Reworked
OscBundle.toString()to produce more readable output for nested bundles. - Added nested alternation support to OSC address pattern compilation and matching.
- Fixed bundle timetag decoding for modern/future OSC timetag values by preserving the raw 64-bit unsigned value during bundle decode.
- Initial Kotlin/JVM OSC library release.
- OSC data model:
OscPacket,OscMessage,OscBundle, and OSC argument types. - Codec APIs:
encodeToByteArrayanddecodeFromByteArray. - Routing and pattern matching:
OscRouterand OSC address matcher/compiler. - UDP runtime:
OscServer,OscClient, and Kotlin DSL builders. - Lifecycle APIs with async idempotent shutdown (
stopAsync/closeAsync). - Project documentation under
docs/and public API compatibility checks (apiCheck/apiDump).
OscTimetag.toInstant()now rejectsOscTimetag.IMMEDIATELYsentinel values.
- Prevented incorrect timestamp conversion when
OscTimetag.IMMEDIATELYwas converted as an absolute timestamp.