Variables
Const authenticate
authenticate: any = client.authenticate.bind(client)
Const command
command: any = client.command.bind(client)
Const downlink
downlink: any = client.downlink.bind(client)
Const downlinkList
downlinkList: any = client.downlinkList.bind(client)
Const downlinkMap
downlinkMap: any = client.downlinkMap.bind(client)
Const downlinkValue
downlinkValue: any = client.downlinkValue.bind(client)
Const hostRef
hostRef: any = client.hostRef.bind(client)
Const isOnline
isOnline: any = client.isOnline.bind(client)
Const keepOnline
keepOnline: any = client.keepOnline.bind(client)
Const laneRef
laneRef: any = client.laneRef.bind(client)
Const nodeRef
nodeRef: any = client.nodeRef.bind(client)
@swim/client
@swim/client is a streaming API client for linking to lanes of stateful Web Agents using the WARP protocol, enabling massively real-time applications that continuously synchronize all shared states with ping latency. WARP is like pub-sub without the broker, enabling every state of a Web API to be streamed, without interference from billions of queues. @swim/client is part of the @swim/mesh framework.
Overview
WarpRef
A
WarpRefis a handle through which WARP downlinks can be opened.WarpClientimplements theWarpRefinterface, as does the exported @swim/client module object, and by extension, the globalswimnamespace object used web browsers and other non-module contexts.WarpRefinstances have four methods that open different kinds of downlinks. Thedownlinkmethod creates anEventDownlinkfor streaming raw events from any Web Agent lane. ThevalueDownlinkmethod creates aValueDownlinkfor synchronizing state with a Web Agent value lane. ThemapDownlinkmethod creates aMapDownlinkfor synchronizing state with a Web Agent map lane. And thelistDownlinkmethod creates aListDownlinkfor synchronizing state with a Web Agent list lane.swim.downlink() .hostUri("warp://traffic.swim.services") .nodeUri("swim:meta:mesh") .laneUri("linkStats") .onEvent((value) => console.log(value.toAny())) .open();WarpRefinstances can also be used to observe key lifecycle events. TheWarpRef.didConnectmethod registers an observer callback that gets invoked whenever a connection to a WARP host is establishes. TheWarpRef.didDisconnectmethod registers an observer callback that gets invoked whenever a WARP host disconnects.WarpRef.didAuthenticateregisters an observer callback that gets invoked whenever the client successfully authenticates with a WARP host.WarpRef.didDeauthenticategets invoked when a WARP host rejects the client's authentication credentials. And theWarpRef.didFailmethod registers an observer callback that gets invoked when the client encounters an unexpected error.swim.didConnect((host) => console.log("connected to", host)); swim.didDisconnect((host) => console.log("disconnected from", host)); swim.didAuthenticate((session, host) => console.log("authenticated to", host, "with session", session.toAny())); swim.didDeauthenticate((reason, host) => console.log("deauthenticated from", host, "because", reason.toAny())); swim.didFail((error, host) => console.log("host", host, "failed because", error));WarpClient
The
WarpClientclass handles connection management and link routing, and implements theWarpRefinterface. In addition to opening downlinks,WarpClientinstances can be used to send arbitrary WARP commands, to provide authentication credentials for hosts, to control network reconnection behavior, and to createHostRef,NodeRef, andLaneRefscopes to facilitate downlink management.The
WarpClient.authenticatemethod associates a credentials structure with a particular host URI. The credentials will be sent in a WARP@authenvelope whenever the client connects to the specified host.swim.authenticate("warps://example.com", {"@openId": jwt});Distinct
WarpClientinstances can be used to create isolated connection pools for different security domains.const userClient = new WarpClient(); userClient.authenticate("warps://example.com", {"@openId": userJwt}); const toolClient = new WarpClient(); toolClient.authenticate("warps://example.com", {"@oauth": toolJwt});The
WarpClient.commandmethod sends a WARP command message to a lane of a remote node.WarpClient.commandtakes either three our four arguments. The three argumentcommandoverload takes a node URI, a lane URI, and a command payload. The node URI must have an authority component that specifies the host to which the command should be sent. The four argumentcommandoverload takes a host URI, a node URI, a lane URI, and a command payload; the node URI is interpreted relative to the host URI.swim.command("warp://example.com/house/kitchen", "light", "on"); swim.command("warp://example.com", "/house/kitchen", "light", "off");The
WarpClient.isOnlinemethod returnstruewhen the the client has access to a network; it can also be used to force a client online or offline. TheWarpClient.keepOnlinemethod controls whether or not the client should automatically reopen connections after a network failure. Note that thekeepOnlinestate of the client overrides thekeepLinkedstate of individual downlinks. SettingkeepOnlineto false can be useful for ephemeral clients, but should typically be lefttrue.swim.isOnline(); // true most of the time swim.isOnline(false); // force offline swim.isOnline(true); // force online swim.keepOnline(); // defaults to true swim.keepOnline(false); // disable network reconnectionThe
WarpClient.hostRefmethod returns a newHostRefbound to the given host URI. TheWarpClient.nodeRefmethod returns a newNodeRefbound to the given host and node URIs. TheWarpClient.laneRefmethod returns a newLaneRefbound to the given host, node, and lane URIs.HostRef
A
HostRefis aWarpRefthat automatically provides its bound host URI when opening downlinks, sending commands, and providing authentication credentials.HostRefinstances keep track of all the downlinks they directly open. When aHostRefis closed, it automatically closes all of its open downlink views.const hostRef = swim.hostRef("warp://traffic.swim.services"); hostRef.downlink() .nodeUri("swim:meta:mesh") .laneUri("linkStats") .onEvent((value) => console.log(value.toAny())}) .open(); // ... hostRef.close();The
HostRef.nodeRefandHostRef.laneRefinstance methods can be used to create further resolvedWarpRefscopes.const hostRef = swim.hostRef("warp://traffic.swim.services"); const nodeRef = hostRef.nodeRef("swim:meta:mesh"); const laneRef = hostRef.laneRef("swim:meta:mesh", "linkStats");NodeRef
A
NodeRefis aWarpRefthat automatically provides its bound host and node URIs when opening downlinks and sending commands.NodeRefinstances keep track of all the downlinks they directly open. When aNodeRefis closed, it automatically closes all of its open downlink views.const nodeRef = swim.nodeRef("warp://traffic.swim.services", "swim:meta:mesh"); nodeRef.downlink() .laneUri("linkStats") .onEvent((value) => console.log(value.toAny())}) .open(); // ... nodeRef.close();The
NodeRef.laneRefinstance method can be used to create further resolvedWarpRefscopes.const nodeRef = swim.nodeRef("warp://traffic.swim.services", "swim:meta:mesh"); const laneRef = nodeRef.laneRef("linkStats");LaneRef
A
LaneRefis aWarpRefthat automatically provides its bound host, node, and lane URIs when opening downlinks and sending commands.LaneRefinstances keep track of all the downlinks they directly open. When aLaneRefis closed, it automatically closes all of its open downlink views.const laneRef = swim.laneRef("warp://traffic.swim.services", "swim:meta:mesh", "linkStats"); laneRef.downlink() .onEvent((value) => console.log(value.toAny())}) .open(); // ... laneRef.close();Downlink
A
Downlinkprovides a virtual bidirectional stream between the client and a lane of a remote Web Agent. WARP clients transparently multiplex all links to Web Agents on a given host over a single WebSocket connection, and automatically manage the network connection to each host, including reconnection and resynchronization after a network failure. WARP clients also seamlessly handle multicast event routing when multiple downlinks are opened to the same lane of the same remote Web Agent.Downlinks come in several flavors, depending on the WARP subprotocol to which they conform. An
EventDownlinkobserves raw WARP events, and can be used to observe lanes of any kind. AValueDownlinksynchronizes a structured value with a remote value lane. AMapDownlinkimplements the WARP map subprotocol to synchronize key-value state with a remote map lane. AListDownlinkimplements the WARP list subprotocol to to synchronize sequential list state with a remote list lane.Before opening, a downlink must be addressed with the
hostUri,nodeUri, andlaneUrito which the link should connect. A downlink may also be configured with a relativepriority, a maxrate, and an optionalbodystructure that can contain query or other link parameters to be passed to the remote lane.The
keepLinkedparameter determines whether or not a downlink should be automatically reopened after a network failure; it defaults totrue. ThekeepSyncedparameter determines whether or not a downlink should synchronize with the remote lane when opened; it defaults totruefor stateful lanes.The
openmethod is used to open a downlink after it has been configured. Theclosemethod closes a downlink. Closing a downlink does not necessarily close the underlying WARP link. The WARP client will keep a link open so long as at least one downlink to a given node and lane URI remains open. This prevents application components from stepping on each other's toes when they link to the same lanes of the same Web Agents. This can happen, for example, when a UI has a summary view and a detail view both display information derived from the same remote lane. The WARP link should not be closed when a detail view is hidden, if state updates are still required by the summary view. Events should also not be sent twice: once for the summary view, and once for the detail view. Neither the summary view nor the detail view should have to know about each other. And no global event dispatcher should be required, which could introduce consistency problems. WARP clients efficiently, and transparently handle all of these cases on behalf of all downlinks.The
isConnectedmethod returnstrueif the underlying connection to the remote host is currently open. TheisAuthenticatedmethod returnstrueif the underlying connection to the remote host is currently authenticated. TheisLinkedmethod returnstrueif the logical WARP link is currently open. And theisSyncedmethod returnstrueif the WARP link is currently synchronized.All downlinks support registering
onEvent,onCommand,willLink,didLink,willSync,didSync,willUnlink,didUnlink,willConnect,didConnect,didDisconnect,didClose, anddidFailcallbacks.EventDownlink
An
EventDownlinkprovides a raw view of a WARP link.swim.downlink() .hostUri("warp://example.com") .nodeUri("/house") .laneUri("power/meter") .onEvent((body) => /* ... */) .open();ValueDownlink
A
ValueDownlinksynchronizes a shared real-time value with a remote value lane. In addition to the standardDownlinkcallbacks,ValueDownlinksupports registeringwillSetanddidSetcallbacks to observe all changes to downlinked state—whether remote or local.A
ValueDownlinkviews its state as a @swim/structureValueby default. Use thevalueFormmethod to create a typed projection of aValueDownlinkthat automatically transforms its state using a @swim/structureForm. For example, you can useForm.foString()to create aValueDownlinkthat coerces its state to a string; and you can also useForm.forAny()to create aValueDownlinkthat coerces its state to a plain old JavaScript value.const value = swim.downlinkValue() .hostUri("warp://example.com") .nodeUri("/house/kitchen") .laneUri("light") .valueForm(swim.Form.forAny()) .didSet((value) => /* ... */) .open();Use the
ValueDownlink.getmethod to get the current state value. Use theValueDownlink.setmethod to set the current state value.value.get(); // get the current local state of the downlink value.set(newValue); // update the local and remote state of the downlinkFor the most part, client code can treat a
ValueDownlinklike an ordinary mutable variable; the WARP client will ensure that the downlink is continuously made consistent with the remote lane. UsingdidSetcallbacks, applications can update UI views, and other dependent components, to keep them consistent with the shared state of the remote value lane in network real-time.swim.downlinkValue() .didSet((value) => { // update UI view with latest value document.getElementById("value").innerText = value; })MapDownlink
A
MapDownlinksynchronizes a shared real-time key-value map with a remote map lane. In addition to the standardDownlinkcallbacks,MapDownlinksupports registeringwillUpdate,didUpdate,willRemove, anddidRemovecallbacks to observe all changes to downlinked map state—whether remote or local.A
MapDownlinkviews its keys and values as @swim/structureValues by default. Use thekeyFormandvalueFormmethods to create a typed projection of aMapDownlinkthat automatically transforms its keys and values using @swim/structureForms.const map = swim.downlinkMap() .hostUri("warp://example.com") .nodeUri("/house") .laneUri("rooms") .keyForm(swim.Form.forString()) .valueForm(swim.Form.forAny()) .didUpdate((key, value) => /* ... */) .didRemove((key) => /* ... */) .open();MapDownlinkimplements the standard JavaScriptMapinterface. Use theMapDownlink.getmethod to get the value associated with a given key. Use theMapDownlink.setmethod to update the value associated with a key. And use theMapDownlink.deletemethod to remove a key and its associated value.map.get("kitchen"); // get the locally cached value associated with the key map.set("garage", newRoom); // locally and remotely insert a new entryFor the most part, client code can treat a
MapDownlinklike an ordinary JavaScriptMap; the WARP client will ensure that the downlink is continuously made consistent with the remote lane. UsingdidUpdateanddidRemovecallbacks, applications can update UI collection views, and other dependent components, to keep them consistent with the shared state of the remote map lane in network real-time.swim.downlinkMap() .didUpdate((key, value) => { if (hasChildElement(key)) { // update existing UI view for key } else { // insert new UI view for key } }) .didRemove((key) => { // remove UI view for key })ListDownlink
A
ListDownlinksynchronizes a shared real-time list with a remote list lane. In addition to the standardDownlinkcallbacks,ListDownlinksupports registeringwillUpdate,didUpdate,willMove,didMove,willRemove, anddidRemovecallbacks to observe all changes to downlinked list state—whether remote or local.A
ListDownlinkviews its items as @swim/structureValues by default. Use thevalueFormmethod to create a typed projection of aListDownlinkthat automatically transforms its items using a @swim/structureForm.const list = swim.downlinkList() .hostUri("warp://example.com") .nodeUri("/house") .laneUri("todo") .valueForm(swim.Form.forAny()) .didUpdate((index, value) => /* ... */) .didMove((fromIndex, toIndex, value) => /* ... */) .didRemove((index) => /* ... */) .open();ListDownlinkbehaves similarly to a JavaScript array. Use theListDownlink.getmethod to get the item at a given index. Use theListDownlink.setmethod to update the item at some index. And use theListDownlink.splicemethod to insert and remove items from the list. You can alsopush,pop,shift, andunshiftitems, andmovean item from one index to another.list.get(0); // get the first item in the list list.set(0, "build"); // locally and remotely update an item list.push("paint"); // locally and remotely append an itemFor the most part, client code can treat a
ListDownlinklike an ordinary JavaScript list; the WARP client will ensure that the downlink is continuously made consistent with the remote lane. UsingdidUpdate,didMove, anddidRemovecallbacks, applications can update UI list views, and other dependent components, to keep them consistent with the shared state of the remote list lane in network real-time.swim.downlinkList() .didUpdate((index, value) => { if (hasChildElement(index)) { // update existing UI view at index } else { // insert new UI view at index } }) .didMove((fromIndex, toIndex, value)) { // move existing UI view from old index to new index } .didRemove((index) => { // remove UI view at index })Installation
npm
For an npm-managed project,
npm install @swim/clientto make it a dependency. TypeScript sources will be installed intonode_modules/@swim/client/main. Transpiled JavaScript and TypeScript definition files install intonode_modules/@swim/client/lib/main. And a pre-built UMD script can be found innode_modules/@swim/client/dist/main/swim-client.js.Browser
Browser applications can load
swim-mesh.js—which bundles the @swim/client library—along with itsswim-core.jsdependency, directly from the swimOS CDN.<!-- Development --> <script src="https://cdn.swimos.org/js/latest/swim-core.js"></script> <script src="https://cdn.swimos.org/js/latest/swim-mesh.js"></script> <!-- Production --> <script src="https://cdn.swimos.org/js/latest/swim-core.min.js"></script> <script src="https://cdn.swimos.org/js/latest/swim-mesh.min.js"></script>Alternatively, the standalone
swim-system.jsscript may be loaded from the swimOS CDN, which bundles @swim/client together with all other @swim/system libraries.<!-- Development --> <script src="https://cdn.swimos.org/js/latest/swim-system.js"></script> <!-- Production --> <script src="https://cdn.swimos.org/js/latest/swim-system.min.js"></script>Usage
ES6/TypeScript
@swim/client can be imported as an ES6 module from TypeScript and other ES6-compatible environments.
import * as client from "@swim/client";CommonJS/Node.js
@swim/client can also be used as a CommonJS module in Node.js applications.
var client = require("@swim/client");Browser
When loaded by a web browser, the
swim-mesh.jsscript adds all @swim/client library exports to the globalswimnamespace. Theswim-mesh.jsscript requires thatswim-core.jshas already been loaded.The
swim-system.jsscript also adds all @swim/client library exports to the globalswimnamespace, making it a drop-in replacement for 'swim-core.js' andswim-mesh.jswhen additional @swim/system libraries are needed.