Co-design permanent, active, stateful, reliable cloud proxies with your web app and gadgets.
Caf.js is built with hierarchies of components configured with JSON descriptions. Parent components monitor children and take recovery action when needed. Component constructors are asynchronous, but the initialization order is deterministic, facilitating dependency injection.
A Cloud Assistant (CA) is similar to an Erlang/OTP actor. It has a queue that serializes message processing, a location-independent name, some private state, and the ability to change behavior, or interact with other CAs. It always checkpoints its state before externalizing it.
Caf.js combines Actors with Distributed Data Structures (DDS) in a novel way. The result is observationally equivalent to a pure Actor system, just faster. Persistent data structures (Immutable.js) help to maintain this property. A DDS can also contain serialized methods, updated atomically with data.
Security mechanisms provide to application writers safe collaborative multi-tenancy. Decentralized authorization borrows from SDSI the linking of globally-identifiable local namespaces; however, it relies on single writer DDSs, not on certificates. Single sign-on uses restricted, signed tokens.
CA sessions can have simple names, chosen by the client, and portable across devices. Names help notification delivery by choosing the best target device. Combined with message serialization and checkpointing, sessions enable exactly-once message delivery for stateless clients.
A Caf.js application bundle has three parts: a web app with React/Redux, a CA, and a device app. Applications are three-way isomorphic, with the CA providing server-side rendering, and introspecting the IoT code. We use Docker containers to deploy both in the Cloud and the device.