These libraries are experimental. APIs may change without notice. Generated from source with koruc 0.1.7 on 11/4/2026.

Enet

@korulang/enet@0.0.1

Reliable + sequenced UDP sessions via libenet, behind phantom obligations

enet/index.kz · 18 tors

@korulang/enet — reliable + sequenced UDP sessions via libenet (v0: IPv4) · 30 more lines
@korulang/enet — reliable + sequenced UDP sessions via libenet (v0: IPv4) Lifts ENet — the connection/channel/reliability layer ENet's own homepage describes as "evolved specifically for Cube" — behind phantom obligations. This is the transport SERVER_CHALLENGE.md names for the Cube 2 slice: sequenced+reliable channels over UDP, connection lifecycle managed by the library, one service call driving handshake/ping/resend. 1. There is no unbound-host state AT ALL. `host` (server) and `client` are the only mints: a *Host exists only once it owns its socket. 2. `close` consumes <!host> — send-after-close is not expressible. 3. `service` fires `! connect` / `! packet` / `! disconnect` once per ENet event, each a scoped borrow valid only inside its branch (the udp `! packet` / raylib `! frame` shape). A borrow's release is auto-inserted at the branch boundary — freeing the koru wrapper, never the ENetPeer, which the library owns for the connection's life. 4. `peer.key` is the peer HANDLE as i64 — the column a server keys per-client rows on (unlike udp's addr fold: a *ENetPeer cannot be refolded from bytes, so the pointer IS the key). send.key casts it back. Session rows drop on `! disconnect` — a stale key reaches a recycled or dead peer slot, which is the named hazard below. 5. `dial` returns `| dialing` with the peer key immediately — the outcome arrives later as a `! connect` on the client's own service, symmetric with the server side. A blocking dial would deadlock a loopback where the same thread must pump both hosts. Service is a poll-shaped drain (timeout honored on the first event wait, then drains queued events at 0): a server calls it once per tick, same shape as libs/udp. The evented socket-source remains the shared named gap (Orisha's kqueue pump is the port source).

Phantom lifecycles

Derived from the phantom labels in the declarations below — state! issues an obligation the compiler will chase, !state discharges it, a bare state holds it without moving it. Nothing here is hand-drawn.

Host 1 state host!
Peer 1 state peer!
Packet 1 state packet!

host

<host!> index.kz:93

client

<host!> index.kz:111

dial

<host> index.kz:128

close

<!host> index.kz:150

service

<host><peer!><packet!> index.kz:161

peer.key

<peer> index.kz:204

peer.pid

<peer> index.kz:207

packet.data

<packet> index.kz:210

packet.channel

<packet> index.kz:213

packet.peer-key

<packet> index.kz:218

packet.peer-pid

<packet> index.kz:222

release.peer

<!peer> index.kz:228

release.packet

<!packet> index.kz:231

send.peer

<peer> index.kz:239

send.key

<host> index.kz:255

peer.disconnect

<peer> index.kz:275

peer.disconnect-key

<host> index.kz:280

flush

<host> index.kz:289