Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
.. framework git workflow jj-config.md jj-init-bare.md jj-init-colocate.md rad-auth-errors.md rad-auth.md rad-block.md rad-checkout-repo-config-linux.md rad-checkout-repo-config-macos.md rad-checkout.md rad-clean.md rad-clone-all.md rad-clone-bare.md rad-clone-connect.md rad-clone-directory.md rad-clone-partial-fail.md rad-clone-scope.md rad-clone-unknown.md rad-clone.md rad-cob-log.md rad-cob-migrate.md rad-cob-multiset rad-cob-multiset.md rad-cob-operations.md rad-cob-show.md rad-cob-update-identity.md rad-cob-update.md rad-config.md rad-diff.md rad-fetch.md rad-fork.md rad-help.md rad-id-collaboration.md rad-id-conflict.md rad-id-multi-delegate.md rad-id-private.md rad-id-threshold-soft-fork.md rad-id-threshold.md rad-id-unauthorized-delegate.md rad-id-unknown-field.md rad-id-update-delete-field.md rad-id.md rad-inbox.md rad-init-detached-head.md rad-init-existing-bare.md rad-init-existing.md rad-init-no-git.md rad-init-no-seed.md rad-init-private-clone-seed.md rad-init-private-clone.md rad-init-private-no-seed.md rad-init-private-seed.md rad-init-private.md rad-init-sync-not-connected.md rad-init-sync-preferred.md rad-init-sync-timeout.md rad-init-sync.md rad-init-with-existing-remote.md rad-init.md rad-inspect-noauth.md rad-inspect.md rad-issue-list.md rad-issue.md rad-key-mismatch.md rad-merge-after-update.md rad-merge-no-ff.md rad-merge-via-push.md rad-node.md rad-patch-ahead-behind.md rad-patch-change-base.md rad-patch-checkout-force.md rad-patch-checkout-revision.md rad-patch-checkout.md rad-patch-delete.md rad-patch-detached-head.md rad-patch-diff.md rad-patch-draft.md rad-patch-edit.md rad-patch-fetch-1.md rad-patch-fetch-2.md rad-patch-jj.md rad-patch-merge-draft.md rad-patch-open-explore.md rad-patch-pull-update.md rad-patch-revert-merge.md rad-patch-update.md rad-patch-via-push.md rad-patch.md rad-publish.md rad-push-and-pull-patches.md rad-remote.md rad-review-by-hunk.md rad-seed-and-follow.md rad-seed-many.md rad-seed-policy-allow-no-scope.md rad-seed-scope.md rad-self.md rad-sync-without-node.md rad-sync.md rad-unseed-many.md rad-unseed.md rad-warn-old-nodes.md rad-watch.md
heartwood crates radicle-cli examples rad-cob-multiset.md

This example demonstrates handling of arbitrary Collaborative Objects (COBs) by means of an external program. The external program is called a “COB helper” (analogous to “remote helpers” that can be used to extend Git). It consumes the current state of the COB and at least one operation (all in JSON) to be applied to it via files whose names are passed as arguments. It returns the resulting COB by printing it to standard output in JSON.

For the sake of example, consider a simplified shopping list, where every item on the list is associated with an integral quantity:

  • 5 Bananas
  • 3 Zucchini
  • 1 Bar of Chocolate

One data structure that maps to this concept very well is a [multiset] (sometimes also called “bag”). So, let us introduce a new COB type with the name com.example.multiset that implements multisets, which we will then use to model our shopping list.

The COB we implement should allow two actions:

  • The action +, which adds an item or, if already present, increases the associated quantity.
  • The action -, which decreases the associated quantity of an item, if it is non-zero.

We model actions as objects in JSON, and a sequence of actions in JSON Lines. An example sequence of actions looks as follows:

{ "+": "jelly" }
{ "+": "peanut butter" }
{ "-": "jelly" }
{ "-": "jelly" }
{ "+": "salad" }
{ "+": "salad" }

Starting with an empty grocery list, the expected result after evaluating all actions is:

  • 0 Jelly (this could be omitted)
  • 1 Peanut Butter
  • 2 Salad

We have a COB helper, named rad-cob-multiset, that implements evaluation of these actions using jq. It reads the current state of the grocery list and operations containing actions from files given as arguments and writes the resulting grocery list to standard output.

We do not invoke the program directly, but instead use rad cob create:

$ rad cob create --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --type com.example.multiset --message "Create grocery shopping multiset" groceries.jsonl
9bba8e6f83ef56b11151ef6ad02cc4595f982aab

We can verify that the COB evaluated as expected:

$ rad cob show --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --type com.example.multiset --object 9bba8e6f83ef56b11151ef6ad02cc4595f982aab
{"jelly":0,"peanut butter":1,"salad":2}

To apply actions to COBs that already exist, we can use rad cob update:

$ rad cob update --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --type com.example.multiset --object 9bba8e6f83ef56b11151ef6ad02cc4595f982aab --message "Modify grocery shopping multiset" groceries.jsonl
d36aac77be13c1ca80edbfe7b7bf9b42c723f019

Again, we verify the result with rad cob show:

$ rad cob show --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --type com.example.multiset --object 9bba8e6f83ef56b11151ef6ad02cc4595f982aab
{"jelly":0,"peanut butter":2,"salad":4}
This example demonstrates handling of arbitrary Collaborative Objects (COBs) by means of an external program.
The external program is called a "COB helper" (analogous to "remote helpers" that can be used to extend Git).
It consumes the current state of the COB and at least one operation (all in [JSON]) to be applied to it via files whose names are passed as arguments.
It returns the resulting COB by printing it to standard output in [JSON].

For the sake of example, consider a simplified shopping list, where every item on the list is associated with an integral quantity:

 - 5 Bananas
 - 3 Zucchini
 - 1 Bar of Chocolate

One data structure that maps to this concept very well is a [multiset] (sometimes also called "bag").
So, let us introduce a new COB type with the name `com.example.multiset` that implements multisets, which we will then use to model our shopping list.

The COB we implement should allow two actions:

 - The action `+`, which adds an item or, if already present, increases the associated quantity.
 - The action `-`, which decreases the associated quantity of an item, if it is non-zero.

We model actions as objects in [JSON], and a sequence of actions in [JSON Lines].
An example sequence of actions looks as follows:

``` ./groceries.jsonl
{ "+": "jelly" }
{ "+": "peanut butter" }
{ "-": "jelly" }
{ "-": "jelly" }
{ "+": "salad" }
{ "+": "salad" }
```

Starting with an empty grocery list, the expected result after evaluating all actions is:

 - 0 Jelly (this could be omitted)
 - 1 Peanut Butter
 - 2 Salad

We have a COB helper, named `rad-cob-multiset`, that implements evaluation of these actions using [jq].
It reads the current state of the grocery list and operations containing actions from files given as arguments and writes the resulting grocery list to standard output.

We do not invoke the program directly, but instead use `rad cob create`:

```
$ rad cob create --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --type com.example.multiset --message "Create grocery shopping multiset" groceries.jsonl
9bba8e6f83ef56b11151ef6ad02cc4595f982aab
```

We can verify that the COB evaluated as expected:

```
$ rad cob show --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --type com.example.multiset --object 9bba8e6f83ef56b11151ef6ad02cc4595f982aab
{"jelly":0,"peanut butter":1,"salad":2}
```

To apply actions to COBs that already exist, we can use `rad cob update`:

```
$ rad cob update --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --type com.example.multiset --object 9bba8e6f83ef56b11151ef6ad02cc4595f982aab --message "Modify grocery shopping multiset" groceries.jsonl
d36aac77be13c1ca80edbfe7b7bf9b42c723f019
```

Again, we verify the result with `rad cob show`:

```
$ rad cob show --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --type com.example.multiset --object 9bba8e6f83ef56b11151ef6ad02cc4595f982aab
{"jelly":0,"peanut butter":2,"salad":4}
```

[multisets]: https://wikipedia.org/wiki/Multiset
[JSON]: https://tools.ietf.org/html/std90
[JSON Lines]: https://jsonlines.org/
[jq]: https://github.com/jqlang/jq