Expand description
§Code MultiPlexer - cooperative development
codemp
is an async client library to create cooperation tools for any text editor.
It is built as a batteries-included client library managing an authenticated user, multiple workspaces each containing any number of buffers.
The Client
is completely managed by the library itself, making its use simple across async
contexts and FFI boundaries. All memory is managed by the library itself, which gives out always
atomic reference-counted pointers to internally mutable objects. Asynchronous actions are
abstracted away by the api::Controller
, providing an unopinionated approach with both
callback-based and blocking-based APIs.
The library also provides ready-to-use bindings in a growing number of other programming languages, to support a potentially infinite number of editors.
§Overview
The main entrypoint is Client::connect
, which establishes an authenticated connection with
a supported remote server and returns a Client
handle to interact with it.
let client = codemp::Client::connect(
codemp::api::Config::new(
"mail@example.net",
"dont-use-this-password"
)
)
.await
.expect("failed to connect!");
A Client
can acquire a Workspace
handle by joining an existing one it can access with
Client::attach_workspace
or create a new one with Client::create_workspace
.
client.create_workspace("my-workspace").await.expect("failed to create workspace!");
let workspace = client.attach_workspace("my-workspace").await.expect("failed to attach!");
A Workspace
handle can be used to acquire a cursor::Controller
to track remote api::Cursor
s
and one or more buffer::Controller
to send and receive api::TextChange
s.
use codemp::api::controller::{AsyncSender, AsyncReceiver}; // needed to access trait methods
let cursor = workspace.cursor();
let event = cursor.recv().await.expect("disconnected while waiting for event!");
println!("user {} moved on buffer {}", event.user, event.sel.buffer);
Internally, buffer::Controller
s store the buffer state as a diamond_types CRDT, guaranteeing
eventual consistency. Each api::TextChange
is translated in a network counterpart that is
guaranteed to converge.
let buffer = workspace.attach_buffer("/some/file.txt").await.expect("failed to attach");
buffer.content(); // force-sync
if let Some(mut update) = buffer.try_recv().await.unwrap() {
println!(
"content: {}, span: {}-{}",
update.change.content, update.change.start_idx, update.change.end_idx
);
buffer.ack(update.version);
} // if None, no changes are currently available
§FFI
As mentioned, we provide bindings in various programming languages. To obtain them, you can compile with the appropriate feature flag. Currently, the following are supported:
lua
javascript
java
(requires additional build steps to be usable)python
For some of these, ready-to-use packages are available in various registries:
Re-exports§
Modules§
- core structs and traits
- buffer related types and controller
- client handle, containing all of the above
- cursor related types and controller
- crate error types
- common utils used in this library and re-exposed
- language-specific ffi “glue”
- all-in-one imports :
use codemp::prelude::*;
- workspace handle and operations
Functions§
- Get the current version of the client