3
2
Fork
You've already forked wyrd
0
An API and plugin interface for treating documents as a series of changes
  • C++ 71.7%
  • C 18.9%
  • Meson 6.1%
  • Python 3%
  • Shell 0.3%
Jens Finkhaeuser 0befebc940
Some checks failed
/ build-meson (arm64, map[cc:clang cxx:clang++]) (push) Successful in 6m36s
/ build-meson (arm64, map[cc:gcc cxx:g++]) (push) Successful in 5m12s
/ build-conan (arm64) (push) Successful in 7m23s
/ checks (push) Has been cancelled
/ build-meson (x86_64, map[cc:clang cxx:clang++]) (push) Has been cancelled
/ build-meson (x86_64, map[cc:gcc cxx:g++], true, true) (push) Has been cancelled
/ build-conan (x86_64) (push) Has been cancelled
/ build-android (android-arm64-v8a.conan) (push) Has been cancelled
/ build-android (android-armeabi-v7a.conan) (push) Has been cancelled
/ build-android (android-x86.conan) (push) Has been cancelled
/ build-android (android-x86_64.conan) (push) Has been cancelled
Add well-known funding url
2024年10月17日 17:43:36 +02:00
.forgejo/workflows Disable appveyor builds for now 2023年12月18日 10:02:34 +01:00
.well-known Add well-known funding url 2024年10月17日 17:43:36 +02:00
changelog.d Add changelog 2024年01月01日 13:40:39 +01:00
docs Bump version: 0.1.0 → 0.1.1 2023年12月30日 15:05:08 +01:00
include (void) and () have different meanings in C 2024年01月09日 13:09:16 +01:00
lib Vessel handles need to also release iterator 2024年01月01日 12:52:10 +01:00
scripts Delete appveyor file 2023年12月18日 10:04:27 +01:00
subprojects The branch no longer exists/has been merged 2023年12月18日 09:42:24 +01:00
test Drop names from unused parameters 2023年12月19日 09:53:20 +01:00
.bumpversion.cfg Bump version: 0.1.0 → 0.1.1 2023年12月30日 15:05:08 +01:00
.gitignore Try this as a skeleton project for Tony 2023年05月08日 17:02:14 +02:00
.gitmodules Try this as a skeleton project for Tony 2023年05月08日 17:02:14 +02:00
.oclint Try this as a skeleton project for Tony 2023年05月08日 17:02:14 +02:00
.semgrepignore Try this as a skeleton project for Tony 2023年05月08日 17:02:14 +02:00
AUTHORS Try this as a skeleton project for Tony 2023年05月08日 17:02:14 +02:00
build-config.h.in WIP 2023年06月28日 11:06:13 +02:00
CHANGES Generate changelog 2023年12月29日 22:22:44 +01:00
CODE_OF_CONDUCT.md Try this as a skeleton project for Tony 2023年05月08日 17:02:14 +02:00
codemeta.json Try this as a skeleton project for Tony 2023年05月08日 17:02:14 +02:00
conandata.yml Include missing header, and set dependency to vessel 0.1.1 2023年12月30日 15:04:54 +01:00
conanfile.py Adjust conanfile to 2.x 2023年12月18日 09:43:35 +01:00
CONTRIBUTING.md Fix docs 2023年12月29日 16:41:25 +01:00
DCO.txt Try this as a skeleton project for Tony 2023年05月08日 17:02:14 +02:00
LICENSE Try this as a skeleton project for Tony 2023年05月08日 17:02:14 +02:00
meson.build Bump version: 0.1.0 → 0.1.1 2023年12月30日 15:05:08 +01:00
meson_options.txt WIP 2023年06月28日 11:06:13 +02:00
Pipfile Merge branch 'main' into documentation 2023年12月13日 13:07:10 +01:00
Pipfile.lock Bump dependencies 2023年12月18日 09:44:05 +01:00
README.md Update README 2024年01月15日 11:17:16 +01:00
towncrier.toml Try this as a skeleton project for Tony 2023年05月08日 17:02:14 +02:00

Wyrd

Build status Project Status: WIP – Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.

An API and plugin interface for treating documents as a series of changes, and synchronizing them across nodes.

Wyrd provides access to documents as a tree structure of properties which can have different data types. In that sense, it is semantically similar to the document representation of e.g. a HTML document, or a nested JSON structure, etc.

Properties are conflict-free replicated data types (CRDTs). Since there exist a number of different CRDTs, when setting a property value, you can also specify a merge strategy, which is effectively a choice of CRDT implementation. When overwriting the value, the merge strategy generates an edit, which can be serialized, sent over a network, and applied on a different node.

The basic implementation uses a file for synchronization: edits are written to a file, and the property tree is reconstructed when the file is read.

However, wyrd also integrates with vessel, which is a container format specifically designed for synchronizing across network nodes. When integrating with vessel, wyrd is more or less equivalent to a Merkle CRDT.

Project Info

ChangeLog Contributing Code of Conduct

💡 Usage

Being a library, the first thing you need to do is instanciate a library handle. This handle contains "global" values, which allows you to run multiple instances in parallel (though that should not be necessary very often):

#include <wyrd/api.h>
/* ... */
struct wyrd_api * api = NULL;
wyrd_error_t err;
err = wyrd_create(&api);
/* use the API instance *
err = wyrd_destroy(&api);

Within the scope of creating and destroying the API instance, you can create as many handles as you need. A handle represents a resource, such as a file or vessel resource.

struct wyrd_handle * handle = NULL;
/* e.g. */
err = wyrd_open_file(api, &handle, "my-file", WYRD_O_RW| WYRD_O_CREATE);
/* use the handle */
err = wyrd_close(&handle);

With an open handle, you can then set and modify properties by name. Property names are strings, but the special . (dot) character separates path segments. Wyrd knows several container property types, such as maps and lists. In this way, a path such as "foo.bar" accesses the property bar which is a child of the foo property, which is in turn a map. Similarly, "foo.0" would access the first element if foo was a list, etc.

In the following example we use the "naive override" merge strategy, which is the simplest form of CRDT - so simple it barely counts. With this strategy, the last change always wins, naively overriding any previous value. But for demonstrating the API, it is the simplest choice:

err = wyrd_set_property_uint16(handle, "foo", WYRD_MS_NAIVE_OVERRIDE, 42);
assert(WYRD_ERR_SUCCESS == wyrd_check_property_type(handle, "foo", WYRD_PT_UINT16));
assert(WYRD_ERR_SUCCESS == wyrd_check_merge_strategy(handle, "foo", WYRD_MS_NAIVE_OVERRIDE));

Finally, for the purpose of reacting to updates from remote nodes, you can register callbacks to be invoked when a property changes.

void my_callback(struct wyrd_handle * handle, char const * path, wyrd_property_type type,
 void const * value, size_t value_size, void * baton)
{
 // This callback can only deal with unchanged property *types*; a more realistic
 // scenario should check the type and act accordingly.
 assert(WYRD_PT_UINT16 == type);
 assert(value_size == sizeof(uint16_t));
 uint16_t val = *((uint16_t const *) value);
 // ...
}
err = wyrd_add_property_callback(handle, "foo", my_callback, NULL);

Whichever you pass as the final parameter to wyrd_add_property_callback will be provided to the callback as the baton parameter. Take care of memory ownership/life cycles with this parameter, as the value cannot be copied.

📖 API

The API is growing as the needs of the Interpeer Project change. The full documentation provides How-Tos and an API reference.

🛠️ Installation

If you're using meson, just put this repo (at a version tag of your choice) into your subprojects as a submodule, e.g.

$ git submodule add https://codeberg.org/interpeer/wyrd subprojects/wyrd
$ cd subprojects/wyrd
$ git checkout v0.1.0 # or whatever
$ cd ..
$ git commit -m "Added wyrd at v0.1.0"

When that is done, you can just use wyrd in your own meson.build file.

# Try system wyrd first, fall back to subproject
wyrd_dep = dependency(
 'wyrd',
 fallback: ['wyrd']
)
# Assuming you're building a list of dependencies
deps += [wyrd_dep]
summary('wyrd', wyrd_dep.version(), section: 'Interpeer Dependencies')

⚖️ License

Wyrd is licensed under the GNU General Public License; a copy of the license is in the repository.

For other licensing options, please contact Interpeer gUG.

We're a non-profit, however, so if you like this library, please consider donating ❤️. That will make sure the code stays maintained.