# atlibs-atirc [atirc](https://tangled.org/johnandersen777.bsky.social/atirc) channels in a browser page, over WebRTC to `atirc mesh run` nodes. No atirc server, no token. ```bash npm install @publicdomainrelay/atlibs-atirc@0.1.0 age-encryption@0.3.1 ``` ## Your VM's node (browser only) On a VM you rent, run your node with a local listener, and ask the contract for the tunnel `{tag: "atirc", port: 7781, transport: "webrtc"}`: ```bash atirc mesh run --local-listen 127.0.0.1:7781 ``` ```js import * as age from "age-encryption"; import { atirc } from "@publicdomainrelay/atlibs-atirc"; // receipt: the contract's {uri, cid}; events/signal: the requester's watch and signal (as WebrtcHost takes them) const chat = atirc({ guests: [{ receipt, events, signal }], age }); const off = chat.onMessage(({ channel, identity, nick, text, ts, seq }) => console.log(channel, nick, text)); await chat.join("#alice_example"); await chat.post("#alice_example", "hi"); await chat.peers(); // { me, channels, peers: [{ did, subhandle }] } chat.close(); ``` ## Your account's mesh Signalled through records (the session needs `repo:computer.socialweb.ingress.offer?action=create&action=delete`): ```js import { atirc, channelOf, sessionRepo } from "@publicdomainrelay/atlibs-atirc"; const chat = atirc({ repo: sessionRepo(session), handle: "alice.example", age }); // an OAuthSession await chat.join(channelOf("alice.example")); ``` It dials the account's own node (`atirc mesh run` as the account, `ATP_PASSWORD` set) first, else every peer whose `computer.socialweb.peer` record names `webrtc` and the channel. ## API | call | | |---|---| | `join(channel)` | resolves once a link is open; history replays first | | `post(channel, text)` | also emits the line (`self: true`) | | `onMessage(fn)` | `fn({channel, identity, nick, did, text, ts, seq, via})`; returns unsubscribe | | `onPresence(fn)` | `fn({channel, event: "join" \| "leave", did, identity})`; returns unsubscribe | | `peers(channel?)` | `{me, channels, peers: [{did, subhandle}]}` | | `leave(channel)`, `close()` | | | `channelOf(name)` | atirc's channel for a handle or identity | Options: `guests [{receipt, events, signal, tag}]` (newest first); `repo`, `handle`, `subhandle` (default `web.`), `owner {did, handle}`, `bridge` (`false` to skip), `peers [{did, subhandle}]`; `age`, `makePeer`. ## Channels - the owner's: `channelOf()`, e.g. `#alice_example` - an agent's own: `channelOf()`, e.g. `#bot_alice_example` `atirc mesh run` carries both by default and joins others a bridge stream asks for. ## Test ```bash npm ci && npm test ``` Loopback (Chrome, Deno, Rust): headless Chrome against three local `atirc mesh run` nodes and a guest (`webrtc-peer`, the guest agent's stand-in): ```bash git clone https://tangled.org/johnandersen777.bsky.social/atirc ../atirc git -C ../atirc checkout 98bd74ae71c0b659fe829d2c521d057a73d61a36 cargo build --manifest-path ../atirc/cli/Cargo.toml git clone https://knotless.dev/johnandersen777.bsky.social/atlibs-webrtc ../atlibs-webrtc git -C ../atlibs-webrtc checkout 735a186d3f86a8755654e970e3daa1174c8a84df cargo build --release --manifest-path ../atlibs-webrtc/Cargo.toml ATIRC_BIN=../atirc/cli/target/debug/atirc WEBRTC_PEER=../atlibs-webrtc/target/release/webrtc-peer \ deno run -A test/loopback.ts ``` Live, against an account's real mesh (runs its own node here; a VM agent of it answers): ```bash ATIRC_BIN=../atirc/cli/target/debug/atirc ATP_USERNAME= ATP_PASSWORD= \ PEERS= deno run -A test/live.ts ```