Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frontend / WARP Client documentation #160

Merged
merged 21 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ collections:
kind: docs
output: true
name: "Backend"
description: Documentation about SwimOS fundamentals and CLI useage.
description: Documentation about SwimOS fundamentals and CLI usage.
permalink: /backend/:name/
order:
- index.md
Expand Down Expand Up @@ -150,6 +150,36 @@ collections:
- recon.md
- warp.md
weight: 1
frontend:
kind: docs
output: true
name: "Frontend"
description: Documentation about streaming data from SwimOS apps for use in UIs.
permalink: /frontend/:name/
order:
- index.md
# Introduction
- whatIsWarp.md
- gettingStarted.md
# Connections
- warpClient.md
- downlinks.md
- valueDownlink.md
- mapDownlink.md
- listDownlink.md
- eventDownlink.md
# - property.md
# - demandLanes.md
# - authentication.md
# Data
- dataModel.md
- structures.md
- form.md
# - structures.md
# Examples/Demos
# Integrations
# - react.md
weight: 1
tutorials:
kind: docs
output: true
Expand Down
6 changes: 6 additions & 0 deletions _data/header-nav.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@
blurb: Learn SwimOS from the start
icon: "fa-brands fa-java"
url: /developer-guide/
- group: Frontend
items:
- title: Frontend Documentation
blurb:
icon: "fa-solid fa-code"
url: /frontend/
- group: Tutorials & Blog
items:
- title: Tutorials
Expand Down
2 changes: 1 addition & 1 deletion _includes/docs-header.html
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,4 @@
</div>

</div>
</nav>
</nav>
31 changes: 31 additions & 0 deletions assets/images/data-model-item-family.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "## Developing Locally",
"main": "postcss.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"launch": "bundle exec jekyll serve --livereload"
},
"author": "",
"license": "ISC",
Expand Down
14 changes: 5 additions & 9 deletions src/_backend/downlinks.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,16 @@ There are two big things to manage when dealing with downlinks: **data** and **c

### Declaration

#### Java

All downlink classes can be imported from package `swim.api.downlink`.

#### Javascript

All downlink types are available after including `swim-core.js`, available from https://cdn.swimos.org/js/3.9.0/swim-core.js.

### Usage

Downlinks must be instantiated against Swim refs, i.e. specific server-side or client-side objects. Although several permutations exist, the builder pattern is the same each time:

1. Invoke `downlink()` against your ref for an event downlink, or `downlinkFoo()` for a foo downlink (e.g. `downlinkMap()` for a map downlink)
1. Build the downlink's `hostUri` using `hostUri()` (this step can only be omitted if your Swim ref is server-side, and you are targeting a lane within the same server), the downlink's `nodeUri` using `nodeUri()`, and the downlink's `laneUri` using `laneUri()`
1. Override any lifecycle callback functions, which default to no-ops
1. In strongly-typed languages (Java, Typescript), optionally parametrize the downlink
1. Optionally parametrize the downlink
1. Optionally set the **keepSynced** (pull all existing data from a lane before processing new updates; defaults to `false`) and **keepLinked** (enable consistent **reads** from the downlink (unnecessary for write-only downlinks); defaults to `true`) flags
1. Invoke `open()` on the downlink to initiate data flow
1. When finished, invoke `close()` on the downlink to stop data flow
Expand Down Expand Up @@ -97,9 +91,11 @@ class CustomClient {

Server-side, downlinks are explained in the [Server Downlinks guide]({% link _backend/server-downlinks.md %}).

#### Javascript
### JavaScript

For details on using downlinks with JavaScript, visit the [**downlinks**]({% link _frontend/downlinks.md %}) article in our [**frontend documentation**](/frontend)

The tutorial application demonstrates [using value downlinks](https://github.com/swimos/tutorial/blob/master/ui/pie.html#L58-L67){:data-proofer-ignore=''} and [map downlinks](https://github.com/swimos/tutorial/blob/master/ui/chart.html#L69-L79){:data-proofer-ignore=''} issued against a Swim client instance. Note the language-level loss of parametrization, but the otherwise-identical syntax to Java.
Furthermore, the tutorial application demonstrates [using value downlinks](https://github.com/swimos/tutorial/blob/master/ui/pie.html#L58-L67){:data-proofer-ignore=''} and [map downlinks](https://github.com/swimos/tutorial/blob/master/ui/chart.html#L69-L79){:data-proofer-ignore=''} issued against a Swim client instance. Note the language-level loss of parametrization, but the otherwise-identical syntax to Java.

### Try It Yourself

Expand Down
2 changes: 1 addition & 1 deletion src/_backend/fundamentals.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ If Web Agents are distributed objects, then [lanes]({% link _backend/lanes.md %}

### Links

Distributed objects need a way to communicate. [Links]({% link _backend/links.md %}) establishes active references to lanes of Web Agents, transparently streaming bi-directional state changes to keep all parts of an application in sync, without the overhead of queries or remote procedure calls.
Distributed objects need a way to communicate. [Links]({% link _backend/links.md %}) establishes active references to lanes of Web Agents, transparently streaming bidirectional state changes to keep all parts of an application in sync, without the overhead of queries or remote procedure calls.

### Recon

Expand Down
2 changes: 1 addition & 1 deletion src/_backend/links.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Native machine pointers also trigger transparent message passing between CPU cor

Links unify edges in an object graph, pointers in a cache coherency system, and subscriptions to mesaging topics, into a single, ultra high performance, easy to use programming primitive.

Links are bi-directional. Either end of a link can update its implicitly shared state in an eventually consistent manner. A link has a downlink side, and an uplink side. The **downlink** side is the one held by the endpoint that opened the link. The **uplink** side is the one held by the endpoint that received the link request.
Links are bidirectional. Either end of a link can update its implicitly shared state in an eventually consistent manner. A link has a downlink side, and an uplink side. The **downlink** side is the one held by the endpoint that opened the link. The **uplink** side is the one held by the endpoint that received the link request.

To open a link, you create a downlink, and specify the address of the Web Agent (called the **node URI**), and the name of the lane (called the **lane URI**) to which you want to link. It's easier than it sounds. Here's what opening a link to a `ValueLane` looks like:

Expand Down
15 changes: 4 additions & 11 deletions src/_backend/swim-libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ redirect_from:
- /reference/swim-libraries.html
---

Swim implements a complete, self-contained, distributed application stack in an embeddable software library. To develop server-side Swim apps, add the [swim-api](https://github.com/swimos/swim/tree/main/swim-java/swim-runtime/swim-host/swim.api) library to your Java project. To write a JavaScript client application, install the [@swim/core](https://github.com/swimos/swim/tree/main/swim-js/swim-core) library from npm. To build a web application, npm install the [@swim/ui](https://github.com/swimos/swim/tree/main/swim-js/swim-ui) and [@swim/ux](https://github.com/swimos/swim/tree/main/swim-js/swim-ux) libraries. Select one of the boxes below (or scroll down) to get started with Swim.
Swim implements a complete, self-contained, distributed application stack in an embeddable software library. To develop server-side Swim apps, add the [swim-api](https://github.com/swimos/swim/tree/main/swim-java/swim-runtime/swim-host/swim.api) library to your Java project. To write a JavaScript client application, install the [@swim/client](https://www.npmjs.com/package/@swim/client) library from NPM. Select one of the boxes below (or scroll down) to get started with Swim.

<!-- <div class="platform-case">
<svg viewBox="0 0 100 100" preserveAspectRatio="none" class="plane">
Expand Down Expand Up @@ -56,20 +56,13 @@ version: "4.2.14"

### JavaScript Client Quick Start

The Swim JavaScript Client is a WARP streaming API client for Node.js and Browser applications.
The Swim JavaScript Client is a WARP streaming API client for Node.js and browser applications.

```console
npm i @swim/core
npm i @swim/client@dev
```

### Web UI Quick Start

The Swim Web UI framework is a dependency-free user interface toolkit for pervasively real-time web applications. It provides everything you need to bind user interface components to WARP streaming APIs. The Swim UX framework implements easy-to-use, procedurally animatable gauges, pies, charts, maps, and more.

```console
npm i @swim/ui
npm i @swim/ux
```
Visit the [**frontend documentation**](/frontend) for more on how to write a JavaScript client application.

### Next Steps

Expand Down
10 changes: 5 additions & 5 deletions src/_backend/warp.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
---
title: WARP
short-title: WARP
description: "The protocol for multiplexing bi-directional streams between large numbers of URIs over a single WebSocket connection"
description: "The protocol for multiplexing bidirectional streams between large numbers of URIs over a single WebSocket connection"
group: Reference
layout: documentation
redirect_from:
- /concepts/warp/
- /reference/warp.html
---

The internet routes packets between physical or virtual machines, identified by IP addresses. On top of the internet sites the World Wide Web you're using right now, which routes requests and responses for Web Resources, identified by URIs. The Web was built for documents. But treating everything like a document is quite limiting. A smart city isn't a document; it's a continuously evolving digital mirror of reality.
The internet routes packets between physical or virtual machines, identified by IP addresses. On top of the internet sits the World Wide Web you're using right now, which routes requests and responses for Web Resources, identified by URIs. The Web was built for documents. But treating everything like a document is quite limiting. A smart city isn't a document; it's a continuously evolving digital mirror of reality.

Things that continuously evolvelike smart cities, autonomous control systems, and collaborative applicationsare best modeled as streams of state changes. We can'tand don't want togive every logical thing in the world an IP address; we want to give things logical names, i.e. URIs. It would be nice if we had a way to route packets between URIslike an application layer network.
Things that continuously evolvelike smart cities, autonomous control systems, and collaborative applicationsare best modeled as streams of state changes. We can'tand don't want togive every logical thing in the world an IP address; we want to give things logical names, i.e. URIs. It would be nice if we had a way to route packets between URIslike an application layer network.

In recent years, the WebSocket protocol has emerged, enabling us to open streaming connections to URIs. This is great. But it only solves part of the problem. Applications need to open a new WebSocket connection for every URI to which they want to connect. This limitation prevents WebSockets alone from serving as a streaming layer of the World Wide Web. But that's OK; that's not WebSocket's role.

WARP is a protocol for multiplexing bi-directional streams between large numbers of URIs over a single WebSocket connection. Multiplexed streams within a WARP connection are called **links**. Just as the World Wide Web has hypertex links between Web Pages, WARP enables actively streaming links between Web Agents.
WARP is a protocol for multiplexing bidirectional streams between large numbers of URIs over a single WebSocket connection. Multiplexed streams within a WARP connection are called **links**. Just as the World Wide Web has hypertext links between Web Pages, WARP enables actively streaming links between Web Agents.

WARP connections exchange WebSocket frames encoded as Recon structures. The use of Recon enables efficient parsing and routing, while preserving the flexibility and extensibility of protocols like HTTP. And the expressiveness of Recon avoids the explosion of specialized grammars and parsers that has caused the originally simple and elegant HTTP protocol to become bloated and complex. It's also worth noting that, although HTTP/2 introduces a limited form of multiplexing, it multiplexes RPC calls, not full-duplex streams.

Having a multiplexed streaming protocol requires a stateful application server to efficiently implement it. Stateful application servers differ from traditional, stateless app servers, in almost every detailfor the better. Swim is a self-contained, stateful application server that implements the WARP multiplexed streaming protocol.
Having a multiplexed streaming protocol requires a stateful application server to efficiently implement it. Stateful application servers differ from traditional, stateless app servers, in almost every detailfor the better. Swim is a self-contained, stateful application server that implements the WARP multiplexed streaming protocol.
29 changes: 29 additions & 0 deletions src/_frontend/dataModel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: Data Model
short-title: Data Model
description: "An overview of the data model contained within the @swim/structure library and why it is used for representing WARP messages."
group: Data
layout: documentation
redirect_from:
---

_This documentation describes Swim JS packages v4.0.0-dev-20230923 or later. Users of earlier package versions may experience differences in behavior._

## Overview

One of the fundamental packages of the Swim JS ecosystem and a dependency of the `@swim/client` library is [**@swim/structure**](https://www.npmjs.com/package/@swim/structure). It contains a set of APIs necessary for reading, parsing, and writing data via WARP links. The "Data" section of the frontend documentation will focus on the classes and tools found within this package and how they enable WARP clients to make sense of the data they're transmitting.

Think of @swim/structure as a generic abstract syntax tree that can represent many structured data models, including parsed JSON, parsed XML, parsed Recon, parsed Protocol Buffers, and more. In addition to structured data models, @swim/structure has generic syntax trees for selector languages, like XPath, JSONPath, and Recon selectors. It also provides generic syntax trees for algebraic, logical, bitwise, and function invocation operators, as well as syntax trees for lambda function definitions. An Interpreter is provided for evaluating selectors, operators, and function invocations.

Parsers from source languages to @swim/structure syntax trees are provided by other packages. The [@swim/recon](https://www.npmjs.com/package/@swim/recon) library implements a parser and serializer for Recon, Recon selectors, and Recon expressions.

## Data Model
The heart of @swim/structure is its uniform structured data model. Swim uses an abstract data model to decouple itself from the irregularities and limitations of common data formats, such as JSON or XML. To illuminate the complexity and limitations this model was designed to solve, let's first consider the data models of JSON and XML.

JSON's data model consists of four primitive types: string, number, boolean, and null; and two composite types: object, and array. Note that because JSON has two distinct composite types, its data model doesn't produce uniform tree structures. JSON also lacks a consistent way to disambiguate polymorphic structures. And JSON's lack of expressiveness leads to frequent use of textual microformats, which require additional parsing steps.

XML's data model consists of one quasi-primitive type: text nodes, which may internally compose out-of-band entity references; and one composite type: element. Note that XML does not produce uniform tree structures either, due to the fact that elements have both child nodes, and associated attributes. And because of its textual nature, XML leads to profuse use of ad hoc string microformats. Rather than natively implementing a structured type system, XML layers on various nominally typed schema languages.

@swim/structure implements a uniform tree data model that is a superset of both the JSON and XML data models. The Swim structured data model has six primitive types: data, text, num, bool, extant, and absent; two field types: attr, and slot; and a single composite type: record.

Having only one composite type allows every compound data structure to be treated as a uniform tree. The record type effectively behaves like a partially-keyed list, enabling it to model both objects and arrays. The attr field type provides a consistent polymorphic disambiguation mechanism, similar to—but more uniform and expressive than—XML tags. The slot field type models object properties as distinct child items that happen to have a key. But unlike JSON object keys, slot keys are not restricted to string values.
Loading