⚠️ Vessels is in development and far from production-ready ⚠️
Contact @syntacticsugarglider on Telegram for inquiries and contribution information.
The basic building block of Vessels is the vessel. A vessel is a WebAssembly binary that exposes a narrow structured interface to the outside world. Each vessel instance spawned has access to its orchestrator singleton, which is what allows the use of capabilities permitted to that vessel. This orchestrator also, with the appropriate capability, allows the registration of capabilities to be delegated in turn and the spawning and management of other vessels and their interconnections.
The communication between vessels, locally and across different machines, is based on a system of Kinds. A Kind is essentially an interface for types with serializable representations, but with bidirectional communication permitted (though not necessarily used) for all Kinds. This communication happens over a dedicated Channel, preventing crosstalk, and the architecture is generically abstracted over the mechanism for delegating channels, the mechanism of serialization and deserialization (JSON / CBOR / etc), and the transport used (network / IPC / vessel-host boundary shared memory / etc). The two operations on Kind are construct and deconstruct, both of which operate on a channel, and both of which are able to read or write on the channel. Channels can be forked to create a subchannel, which is used to allow Kinds to send sub-Kinds (for example, having a list of Kinds also itself be a Kind).
A vessel itself must export a single Kind. This is called satisfying the Kind exported. A vessel can be provided across boundaries in a manner similar to “passing by reference” in which calls to the vessel are sent over the channel back to the deconstructor, which calls the original concrete instance and sends the return values back. Capabilities received from the orchestrator are generally Kinds provided in this manner, such as to provide access to abstracted hardware features or vessel orchestration. A vessel can also be sent in a manner similar to “passing by move” where the WASM binary itself is sent over the wire and instantiated transparently by the recipient (assuming that recipient possesses the requisite capabilities to request the orchestrator to instantiate this new vessel). For example, a request for a video transcoder capability could either be replied to with a “passed by reference” vessel providing access to NVENC or similar in hardware locally, or with a “passed by value” vessel that provides software transcoding and is instantiated by the recipient. All use of vessels is transparent to the developer and requires no boilerplate additional to that which would be required for equivalent concrete types. In fact, vessels are used directly as the concrete Kind they export, appearing transparently equivalent to that underlying type.
Vessels also provides an advanced reflection and dynamic casting system for interface erasure. Not only does Vessels provide a mechanism, the Kind derive macro, for implementing Kind for arbitrary structs and enums with no additional effort, it also provides the object macro which implements Kind for trait objects. These trait objects can be erased to a single type, reflected for individual methods, introspected for supertraits, and cast back into both their own concrete object type and concrete objects of their supertraits in a fully checked manner. This allows elegant dynamically-typed patterns for runtime composability, with vessel components implementing various traits and lenses and prisms permitting their appropriate interpretation for various ecosystem contexts.
Kind is implemented for many common types as well as other crucial constructs such as boxed functions and futures/streams, derivation systems are fully working, use of Kinds over Channels is fully working. The reference Channel implementation,
IdChannel, is fully working. Kinds can be exported from WebAssembly binaries, i.e. vessels, but the infrastructure required for their convenient use is not yet implemented. The core provider is implemented but does not yet provide an orchestrator due to the prior point, however a global executor is available and vessels can schedule tasks. The reflection engine is fully functional but, at the moment,
Erased is not yet a Kind object. This should be resolved shortly. Feature parity for all enumerated above exists across web and native and such parity will continue to be a goal. The current priority is the finalization of the core abstractions, with mostly orchestration systems and hardware abstraction remaining at this point, and the completion of reference systems, mostly
IdChannel, such that demos and the first primitives of a growing ecosystem can be implemented.