Build Real-Time
Web Applications

Transform stateless Web Services into stateful Web Agents
that continuously collaborate with users and with each other.

Active Apps

By remembering their own state, and the state of their relations, Web Agents can autonomously operate with comprehensive real-time context.

Streaming APIs

Because they run uninterrupted, Web Agents can communicate with users, and other agents, to keep everyone in sync about everything they want to know.

Real-Time UIs

Without having to guess when to refresh, user interfaces can bind widget state to Web Agent state and remain up-to-date within the latency of the network.

Web Agent Manifesto

We live in a world of connected devices and real-time data streams. It’s no longer sufficient to share snapshots.
1

Create a stateful Web Agent

A Web Agent is ordinary object, with extraordinary capabilities. Instead of being addressed by a local memory address, a Web Agent is addressed by a Universal Resource Identifier (URI). Web Agents are stateful—they remember their instance variables between operations. Special instance variables, called lanes, also persist state locally, and expose bidirections streaming APIs.

public class DiceAgent extends AbstractAgent {
  @SwimLane("status")
  ValueLane<Number> status;
}
2

Stream changes to remote Web Agent state

A Downlink forms a refernces to the shared state of another Web Agent. Downlinks synchronously access remote agent state as if it were local. Real-time cache coherency is continuously performed in the background, keeping all views of the same shared state in sync.

ValueDownlink<Number> status = downlinkValue()
    .valueClass(Number.class)
    .nodeUri("warp://example.com/dice")
    .laneUri("status")
    .didSet((newValue: Number, oldValue: Number) -> {
      System.out.println("rolled a " + newValue);
    })
    .open();
3

Remotely update Web Agent state

Like a distributed pointer, downlinks allow shared states to be read from and written to. A continuously consistent memory model ensures that all views of the same shared state eventually converge. The principles used by multicore computers apply to distributed computers too.

ValueDownlink<Number> status = downlinkValue()
    .valueClass(Number.class)
    .nodeUri("warp://example.com/dice")
    .laneUri("status")
    .open();

status.set(Math.round(6 * Math.random()));
4

Schedule autonomous Web Agent actions

Web Agents don't need to wait for external requests to take action. Because they run continuously, agents can run general purpose code. Never underestimate the power of a humble timer.

public class AutonomousAgent extends AbstractAgent {
  @Override
  public void didStart() {
    setTimer(10000, () -> {
      // the future is now
    }
  }
}
5

Bind a user interface to shared Web Agent state

Real-time user interfaces synchronize the state of Web Agents with their User Agent overlords—that means you.

const mapView = new swim.MapboxView(map);
const vehiclesLink = swim.downlinkMap()
    .hostUri("warp://transit.swim.services")
    .nodeUri("/state/US/S-CA")
    .laneUri("vehicles")
    .didUpdate(function (key, value) {
      const lng = value.get("longitude").numberValue(0);
      const lat = value.get("latitude").numberValue(0);
      let vehicle = mapView.getChildView(key.stringValue());
      if (vehicle) {
        vehicle.center([lng, lat], {duration: 10000});
      } else {
        vehicle = new swim.MapCircleView().center([lng, lat]).radius(5).fill("#00a6ed");
        mapView.setChildView(key.stringValue(), vehicle);
      }
    })
    .open();
The open source swimOS platform is a modern approach to distributed applications without the usual operational headaches.
— Krish Subramanian, Rishidot Research