NearbyLoom

class NearbyLoom(api: NearbyApi, serviceId: String = DEFAULT_SERVICE_ID, policy: DeliveryPolicy = DeliveryPolicy.Reliable, handshakeTimeout: Duration = DEFAULT_HANDSHAKE_TIMEOUT, maxChunkPayload: Int = ChunkCodec.MAX_CHUNK_PAYLOAD) : Loom

Loom implementation backed by Google Nearby Connections.

All logic is GMS-free and lives in commonMain. The real binding that imports play-services-nearby is supplied by androidMain at construction time.

Concurrency and virtual-time correctness

Background coroutines are launched into a scope derived from the caller's coroutine context at open()/join() time: CoroutineScope(currentCoroutineContext() + SupervisorJob()). This means background work inherits the test dispatcher (and therefore runTest's virtual clock) when tests call these methods. The scope is stored and cancelled in NearbySeam.close so no coroutines leak between tests. There is no long-lived process-global scope.

Single-loom symmetric topology

One NearbyLoom handles both the advertiser role (open) and the discoverer role (join) through the same NearbyApi. Both seams share a single sharedPeers StateFlow. This matches the us.tractat.kuilt.core.InMemoryLoom pattern and lets the conformance suite run a "one loom, one host, one joiner" scenario.

No loom-level selfId — identity is minted per weave

Because one loom weaves both ends of a session (above), a loom-level identity would hand the host seam and the joiner seam the same PeerId — collapsing the roster to one entry, so Weaving would never reach Woven, and making every sendTo between them fail its own peer != selfId precondition. Each weave therefore mints its own us.tractat.kuilt.core.freshPeerId, exactly as us.tractat.kuilt.core.InMemoryLoom does. That is why the uniform-Loom-construction convention's selfId knob is deliberately absent here rather than defaulted (#1430); NearbyLoomKnobsTest pins the distinctness the omission rests on.

Parameters

api

NearbyApi to use (real GMS or fake for tests).

serviceId

Nearby Connections service ID. Must match on both devices.

policy

Delivery policy for every woven seam's inbound buffer.

handshakeTimeout

Ceiling on ONE connection's handshake, forwarded to ConnectStateMachine. Not a weave timeout — endpoint discovery sits outside it (see DEFAULT_HANDSHAKE_TIMEOUT).

maxChunkPayload

Per-chunk payload cap forwarded to ChunkCodec.

Constructors

Link copied to clipboard
constructor(api: NearbyApi, serviceId: String = DEFAULT_SERVICE_ID, policy: DeliveryPolicy = DeliveryPolicy.Reliable, handshakeTimeout: Duration = DEFAULT_HANDSHAKE_TIMEOUT, maxChunkPayload: Int = ChunkCodec.MAX_CHUNK_PAYLOAD)

Types

Link copied to clipboard
object Companion

Functions

Link copied to clipboard
Link copied to clipboard
open override fun capability(): TransportCapability
Link copied to clipboard
open suspend fun host(pattern: Pattern): Seam
Link copied to clipboard
open suspend fun join(tag: Tag): Seam
Link copied to clipboard
open suspend override fun weave(rendezvous: Rendezvous): Seam