pamoja for TypeScript - v0.2.0
    Preparing search index...

    Module @pamoja/coap

    Ergonomic facade over the generated CoAP binding.

    CoAP is the transport for links where MQTT is more than the budget allows: it runs over UDP, its headers are a handful of bytes, and a node can fire a reading and forget it rather than holding a session open. A CoapClient is the node's end, and a CoapServer the gateway it reports to.

    The reliability choice is re-exported as a runtime Reliability object, because the generated enum is types-only.

    @pamoja/coap

    A CoAP client and the server it reports to, over UDP, with confirmable delivery and observe. One capability of pamoja, one memory-safe Rust core with bindings for TypeScript, Python, and C#.

    read the guide documentation API reference

    npm install @pamoja/coap
    

    This pulls in @pamoja/native, the compiled engine. npm install pamoja is the whole framework in one package.

    The test that runs in CI, spliced here as it ran.

    From bindings/node/guides/coap.ts:

    import { CoapClient, CoapServer, Reliability } from '@pamoja/coap'

    async function main() {
    // The gateway in the orchard's shed. It takes moisture readings from every row, and holds
    // the irrigation valve's state for the rows to observe. Port 0 lets the system pick a free
    // port, which the rows are pointed at below.
    const gateway = new CoapServer('127.0.0.1:0')
    await gateway.connect()
    await gateway.subscribe('orchard/+/moisture')
    await gateway.send('orchard/valve', 'closed')
    const port = gateway.localPort!
    console.log('gateway takes moisture readings on orchard/+/moisture')

    // A battery-powered sensor in row 7. Its reading is confirmable, so it waits for the
    // gateway's acknowledgment and retransmits until one comes back.
    const row7 = new CoapClient({ host: '127.0.0.1', port, ackTimeoutMs: 200 })
    await row7.connect()
    await row7.send('orchard/row-7/moisture', '31')
    console.log('row-7 reported 31, and the gateway acknowledged it')
    const reading = (await gateway.recv())!
    console.log(`gateway took ${reading.text!} from ${reading.topic}`)

    // Observing the valve registers the row with the gateway, which answers with the valve's
    // state now and notifies every change after it, as RFC 7641 describes.
    await row7.subscribe('orchard/valve')
    const current = (await row7.recv())!
    console.log(`row-7 observes ${current.topic}, which reads ${current.text!}`)
    await gateway.send('orchard/valve', 'open')
    const observers = gateway.observers('orchard/valve')
    console.log(`gateway opened the valve for ${observers} observer`)
    const change = (await row7.recv())!
    console.log(`row-7 ${change.topic} now reads ${change.text!}`)

    // A path the gateway does not take is answered 4.04, and a confirmable send reports that
    // rather than counting the reading as delivered.
    try {
    await row7.send('orchard/row-7/battery', '3.1')
    console.log('row-7 the battery reading was taken, which should never happen')
    } catch (error) {
    console.log(`row-7 battery refused: ${(error as Error).message}`)
    }

    // Row 8 sends non-confirmable: once and unacknowledged, which costs the least radio time
    // and suits a reading whose loss costs nothing.
    const row8 = new CoapClient({ host: '127.0.0.1', port, reliability: Reliability.NonConfirmable })
    await row8.connect()
    await row8.send('orchard/row-8/moisture', '27')
    console.log('row-8 sent 27 without waiting for an answer')
    const unconfirmed = (await gateway.recv())!
    console.log(`gateway took ${unconfirmed.text!} from ${unconfirmed.topic}`)

    // Row 9 is pointed at port 1, where nothing listens. A confirmable send retransmits on a
    // doubling wait and then gives up. RFC 7252's defaults would take more than a minute to
    // get there, so this one waits 20 ms and retransmits once.
    const row9 = new CoapClient({ host: '127.0.0.1', port: 1, ackTimeoutMs: 20, maxRetransmits: 1 })
    await row9.connect()
    try {
    await row9.send('orchard/row-9/moisture', '29')
    console.log('row-9 an empty port acknowledged it, which should never happen')
    } catch (error) {
    console.log(`row-9 gave up unacknowledged: ${(error as Error).message}`)
    }

    for (const link of [row7, row8, row9]) {
    await link.disconnect()
    }
    await gateway.disconnect()
    return { reading, current, change, observers, unconfirmed }
    }

    main()
    Language Package Reference
    Rust pamoja-coap reference, docs.rs, install
    TypeScript @pamoja/coap reference, install
    Python pamoja-coap reference, install
    C# Pamoja.Coap reference, install

    MIT

    ReliabilityName
    CoapClient
    CoapServer
    CoapClientOptions
    TransportMessage
    Reliability
    Reliability