TypeScript
Browsers and Node 22 or later. The protocol, the sessions and the persisted state are the same Rust the native heads run, compiled to WebAssembly; the TypeScript around it fetches the service document, opens one WebSocket per service, and gives the client a JavaScript shape. A page needs nothing but HTTPS.
Not on npm yet: the package is built from the repository. Everything else on this page runs today, and the repository's own test runs it in Node on every commit.
Build the package
From a checkout of the
tacenta repository,
with Rust, the wasm32-unknown-unknown target, wasm-pack and
Node installed:
cd sdk/typescript
npm install
npm run build:wasm
npm run build
That leaves the package in place, ready to install into an app with
npm install ../path/to/tacenta/sdk/typescript.
Send a message
import { Tacenta } from "@tacenta/sdk";
const tenant = await Tacenta.connect("tct_your_api_key");
await tenant.signUp("alice", "correct horse");
await tenant.signUp("bob", "correct horse");
const alice = await tenant.signIn("alice", "correct horse");
const bob = await tenant.signIn("bob", "correct horse");
const toBob = await alice.find("bob");
if (toBob) await alice.send(toBob, "hello from the browser");
for await (const m of bob.inbound()) {
console.log(m.from, m.text());
} inbound() is the client's messages one at a time as they
arrive; receive() is the same as batches. A pending one does
not hold the client, so a send from elsewhere goes through
meanwhile. tacenta init typescript writes this sample, with
your key in place, as a project.
connect fetches the server's service document from
https://tacenta.com/.well-known/tacenta and holds it to the
same rule the native client applies: over HTTPS it may not turn encryption
off or send your users anywhere but the domain it came from. For a
self-hosted server pass { server: "chat.example.org" };
for a local development gateway,
{ documentUrl: "http://127.0.0.1:4780/.well-known/tacenta" }.
Keep the identity across runs
A client's identity and its live sessions can be exported and resumed, so a conversation continues after a reload rather than starting over. Store the bytes where your app keeps secrets: IndexedDB in a page, a file or a keychain in Node.
const state = await alice.exportState();
// later, on the next run:
const again = await tenant.signInWithState("alice", "correct horse", state); What this head does not have yet
- Sealed state
- The rollback-resistant state path and the secure-store hook the Swift and Kotlin heads have are not on this head yet.
- A published package
- Build it from the repository for now; the shape above is the shape that will publish.
Reference
The generated reference, TypeDoc of the package, regenerated at every release from the code it documents: tacenta.com/dl/reference/typescript/.