UNAVI Docs unavi.xyz
Build · Scripting API

wired:event

Messages between scripts on this peer.

Nothing here crosses the network. Every peer runs the same scripts, so each peer's copy of a script sends its own messages to the scripts beside it. Anything that must agree across peers belongs in a shared property.

Channels are a flat namespace any script can guess. Name them <namespace>:<package>/<name> to avoid collisions, and filter by sender where it matters who is speaking.

Interface messaging

Uses document-id, prim-ref, error.

spatial

record

A sphere around a prim of a document the script may write.

origin: prim-ref
radius: f32Meters.

scope

variant

Where a message is heard. A spatial message reaches a spatial listener only when their spheres overlap, and reaches every global listener. A global message reaches global listeners only.

global
spatial(spatial)

message

record
channel: string
payload: list<u8>
sender: option<document-id>The sending script's document, or none for the host.
distance: option<f32>Meters between the two origins, when both were spatial.
sent-at: f64When it was sent, in seconds on this peer's clock.
claim-token: option<u64>Present when the sender named an audience. Pass it to message-subscription.claim to take the message from the rest of the audience.

message-subscription

resource

Holds up to 64 messages.

drain

methoddrain: func(max: u32) -> list<message>

dropped

methoddropped: func() -> u64

claim

methodclaim: func(token: u64) -> bool

Takes a message the sender addressed to an audience, answering whether this subscription won it: exactly one listener in the audience does. A subscription remembers the tokens of its 256 most recent addressed messages. An older one loses.

emit

funcemit: func(channel: string, payload: list<u8>, audience: option<list<document-id>>, scope: scope) -> result<_, error>

Sends payload on channel to every matching listener, or only to those of the documents in audience. A channel is at most 256 bytes, a payload 64 KiB, and an audience 64 documents.

listen

funclisten: func(channels: list<string>, senders: option<list<document-id>>, scope: scope) -> result<message-subscription, error>

Hears channels, from any sender or only the documents in senders. At most 32 channels and 64 senders.

Source

/// Messages between scripts on this peer.
///
/// Nothing here crosses the network. Every peer runs the same scripts, so
/// each peer's copy of a script sends its own messages to the scripts beside
/// it. Anything that must agree across peers belongs in a `shared` property.
///
/// Channels are a flat namespace any script can guess. Name them
/// `<namespace>:<package>/<name>` to avoid collisions, and filter by sender
/// where it matters who is speaking.
package wired:event;

interface messaging {
  use wired:core/ids.{document-id, prim-ref};
  use wired:core/error.{error};

  /// A sphere around a prim of a document the script may write.
  record spatial {
    origin: prim-ref,
    /// Meters.
    radius: f32,
  }

  /// Where a message is heard. A spatial message reaches a spatial listener
  /// only when their spheres overlap, and reaches every global listener. A
  /// global message reaches global listeners only.
  variant scope {
    global,
    spatial(spatial),
  }

  record message {
    channel:     string,
    payload:     list<u8>,
    /// The sending script's document, or `none` for the host.
    sender:      option<document-id>,
    /// Meters between the two origins, when both were spatial.
    distance:    option<f32>,
    /// When it was sent, in seconds on this peer's clock.
    sent-at:     f64,
    /// Present when the sender named an audience. Pass it to
    /// `message-subscription.claim` to take the message from the rest of the
    /// audience.
    claim-token: option<u64>,
  }

  /// Sends `payload` on `channel` to every matching listener, or only to
  /// those of the documents in `audience`. A channel is at most 256 bytes, a
  /// payload 64 KiB, and an audience 64 documents.
  emit: func(
    channel:  string,
    payload:  list<u8>,
    audience: option<list<document-id>>,
    scope:    scope,
  ) -> result<_, error>;

  /// Hears `channels`, from any sender or only the documents in `senders`.
  /// At most 32 channels and 64 senders.
  listen: func(
    channels: list<string>,
    senders:  option<list<document-id>>,
    scope:    scope,
  ) -> result<message-subscription, error>;

  /// Holds up to 64 messages.
  resource message-subscription {
    drain:   func(max: u32) -> list<message>;
    dropped: func() -> u64;
    /// Takes a message the sender addressed to an audience, answering
    /// whether this subscription won it: exactly one listener in the
    /// audience does. A subscription remembers the tokens of its 256 most
    /// recent addressed messages. An older one loses.
    claim:   func(token: u64) -> bool;
  }
}