Skip to main content

AI quick reference

IOSignal JavaScript 7.2.0 · documentation baseline 2026-10-19 · sourceCommit cd03bbf1606098571bac3e03d02459e1a9a86a5f (iosignal repository main, Node.js 22.16.0 or later). Arduino, CLI, and Boho are separate packages.

This is a one-page summary. Verify details and exceptions in the AI guide, client API, and server API. If the installed version differs from 7.2.0, use that version's types, source, and tests.

Imports and installation​

EnvironmentCode
Node.jsimport { IO, Server } from 'iosignal'
Browser bundlerimport IO from 'iosignal/io'
Browser CDNhttps://cdn.jsdelivr.net/npm/iosignal@7.2.0/dist/browser/iife/io.js
Installnpm install --save-exact iosignal@7.2.0

The root iosignal entry is for Node.js. Do not use import { IO } from 'iosignal' in a browser; use the bundler path iosignal/io or the IIFE/ESM browser build from a CDN.

Connection and lifecycle​

import { IO } from 'iosignal';

const io = new IO();
const tag = 'room#chat';

io.on('message', (tag, ...args) => {
// Channel subscriptions and CID-published subscriptions.
});

io.on('@', (tag, ...args) => {
// All direct signals (no subscription needed).
});

io.on('ready', () => {
io.subscribe(tag); // Re-register manual subscriptions on every ready.
io.signal(tag, { hello: io.cid }); // Send after ready.
});

io.listen('alarm#state', (tag, ...args) => {
console.log(tag, ...args);
});
io.open('ws://localhost:7777');
  • Socket open is not IOSignal ready. Use the CID, manual subscriptions, and sends after ready.
  • ready fires again after reconnection. io.cid may differ per connection, so read it every time.
  • Manual subscribe() calls do not survive reconnection. Register them again in the ready handler.
  • For normal tags, listen() subscribes on ready and after reconnection. Direct tags (@, @topic) need no subscription.
  • on() only registers a handler; it does not subscribe.

Tags​

PurposeSend tagSubscribe tagHandler tag
Normal channelroom#topicroom#topicroom#topic
Direct to BB@topicnot needed@topic
CID publish@topicA@topicA@topic
Home channel#topic#topic#topic
  • Tags are limited to 255 UTF-8 bytes, not JavaScript string characters.
  • #topic is a HOME CHANNEL grouped by external IP; it is not authentication or a trust boundary.
  • In room#topic, room is the channel and topic is the topic. Hierarchical topics are not supported.
  • Calling subscribe('@topic') or unsubscribe('@topic') for direct reception throws TypeError. Use on() or listen(). A@topic is allowed because it is a CID-publish subscription.

Payloads​

io.signal('room'); // EMPTY → (tag)
io.signal('room', 'hello'); // TEXT → (tag, 'hello')
io.signal('room', new Uint8Array([1, 2])); // BINARY → (tag, binary)
io.signal('room', {value: 42}); // OBJECT → (tag, {value: 42})
io.signal('room', 'value', 42); // MJSON → (tag, 'value', 42)
io.signal('room', 42); // TEXT → (tag, '42')
  • A single number is converted to TEXT. Use an object or multiple arguments to preserve a number.
  • JS restores OBJECT/MJSON/MBA automatically, but Arduino callbacks receive only the type, raw bytes, and length.
  • A signal() call does not confirm that the peer finished its business logic. Design an application reply when needed.

Direct signals​

// Send directly to a peer.
io.signal(peerCid + '@rtc', {type: 'offer', sdp});

// Receive: '@' then the exact '@rtc' event; 'message' is not emitted.
io.on('@rtc', (tag, message) => {
console.log(tag, message); // '@rtc', {type: 'offer', sdp}
});

Registering the same processing on both '@' and '@rtc' can handle one message twice. Direct reception needs no server subscription.

Quota and size limits​

  • Quota is not a fixed library constant; the server operator configures it for the service.
  • After ready, read io.level and io.quota.signalSize for the current connection. Do not hard-code a value.
  • Release defaults in serverOption are references only. In production, set defaultQuotaIndex, useQuota, and authentication levels explicitly.
  • The 255-byte tag limit is a protocol rule, separate from quota.
  • Sends above signalSize are skipped and may emit over_size. Check the size before sending a large payload.

Reconnection​

io.on('ready', () => {
io.subscribe(tag); // Re-register manual subscriptions.
rebuildPeers(io.cid); // Rebuild peer and room state for the new CID.
});
  • Public servers may redirect before the first ready. Distinguish that from a disconnect after readiness and bound the wait.
  • Do not assume peer lists or room state keyed by CID remain valid after reconnection.
  • The library re-sends normal-tag subscriptions registered through listen().
  • rebuildPeers() in the example is an application function, not a library API.
  • Call destroy() when a component solely owns the IO instance. For a shared instance, release only the component's link registrations with unlinkAll(component). It removes handlers registered through link() for that component and subscriptions owned only by those links; handlers registered with on() or listen() are not removed.

Arduino​

  • Arduino uses a separate library and does not restore JS objects automatically. Parse the type, raw bytes, and length from the onMessage callback.
  • Tag and payload limits follow the same protocol rules. Check the board's memory and buffer size.
  • Follow Arduino introduction and installation for connection maintenance and board wiring.

Working with AI​

  • Do not invent undocumented APIs; verify against the installed version's types, source, and tests.
  • Report the runtime, installed version, sourceCommit, run commands, tests performed, and untested scope.
  • Separate library guarantees from application rules such as room capacity, permissions, and message formats.

Full documentation​