ddat interop with dat js cable interop with cabal js ddat's frontend = dat-thang cable fe = cable-thang dillo support based on cel's dillo-dat bootstrap node xplatform support Signed-off-by: divo <418@cryspace.space>
155 lines
8.0 KiB
Markdown
155 lines
8.0 KiB
Markdown
# Cable and Cabal interoperability notes
|
|
|
|
This document describes the **test-only Cabal/Hypercore interoperability
|
|
harness** under `tests/interop/cabal/`. It is kept to compare historical
|
|
behavior and is excluded from production builds and runtime paths.
|
|
|
|
The production `cable` and `cable-thang` clients are C/S7 applications:
|
|
Cesspool handles discovery and transport, Sleep handles persistent local
|
|
feeds, and S7 represents room events as S-expressions. Cabal CLI and
|
|
Hypercore are test targets, not production dependencies.
|
|
|
|
## Which client to run
|
|
|
|
The working historical Cabal terminal client is `cabal-cli`. To join a room,
|
|
run:
|
|
|
|
```sh
|
|
cabal-cli cabal://<room-key>
|
|
```
|
|
|
|
The `cable` executable also supports local Sleep feed and Cesspool bootstrap
|
|
commands. The native Cable chat client is `cable-thang`, using a terminal-style
|
|
SDL2 layout inspired by Cabal's TUI. Build with `make ENABLE_SDL2=1`; create an
|
|
address in the terminal with `build/linux/cable --new`, then launch the GUI with
|
|
`build/linux/cable-thang <cable://address>`. Use `/join NAME`, `/nick NAME`,
|
|
`Ctrl+N`, and `Ctrl+P` in the client.
|
|
|
|
## Cabal behaviors being ported
|
|
|
|
The Cabal CLI's `/whoami` (also `/key`) displays the local user key, while
|
|
`/nick` changes that user's display name. Those are different things: the
|
|
user's public key is the stable identity within that room; the nickname is a
|
|
readable label published as an `about` record in that user's room feed.
|
|
The CLI's usage and commands are listed in the
|
|
[cabal-cli README](https://github.com/cabal-club/cabal-cli#commands). The
|
|
[cabal-core API](https://github.com/cabal-club/cabal-core#cabalgetlocalkeycb)
|
|
documents `getLocalKey()` as the local user's key and documents messages as
|
|
records published to user feeds. Cabal creates its local writer feed inside
|
|
each room's storage, so a user's key is room-scoped, stable for that room, and
|
|
can differ in another room. A room key and its optional `?admin=<key>`
|
|
moderation key are separate from each user's feed key. Cabal text records use
|
|
`chat/text` with channel and text fields.
|
|
|
|
## Dat-era Cabal reference
|
|
|
|
Cabal Core 5.0.1 is a concrete older reference candidate: it was published about
|
|
seven years ago, and a 2019 Cabal walkthrough describes the chat as running
|
|
over Dat (the walkthrough was later updated for Cabal Core 5.0). The bundled
|
|
Dillo Dat tree supplies a nearby protocol reference with Hypercore 7.7.1,
|
|
hypercore-protocol 6.12.0, Hyperdrive 9.16.0, and hyperdiscovery 7.1.1. Use
|
|
those versions to guide backwards-adaptation; do not treat current Cabal Core
|
|
16 or its Hyper:// networking as the target.
|
|
|
|
The repeatable JS behavior tests remain useful for room identity, nicknames,
|
|
channels, and record shapes. To run them against the historical package, point
|
|
CABAL_JS_MODULE and CABAL_CLIENT_MODULE at a Cabal Core 5.0.x install, then run
|
|
make test-cabal-interop.
|
|
|
|
## Current C groundwork
|
|
|
|
- `cable address` accepts room keys with `cabal://`, `cable://`, or
|
|
`hyper://`, including a `?admin=<64 hex>` parameter, and prints canonical
|
|
`cable://` room addresses while retaining the admin key separately.
|
|
- `cable whoami <room-address>` and dat-thang expose a persistent local user
|
|
key as a `cable://<64 hex>` user address. Each room gets its own 64-byte
|
|
Ed25519 secret at `~/.cable/rooms/<room-key>/user-feed.key`, with owner-only
|
|
permissions. The key is stable in that room across restarts and distinct
|
|
from the room and admin keys.
|
|
- `hyper://` parsing only aliases the key representation; production Cable
|
|
does not implement the newer Hypercore stack.
|
|
- The library defines a bounded Cable text-message envelope and libsodium
|
|
sealed-box encrypt/decrypt helpers.
|
|
- dat-thang's left panel is a peer list again. Double-clicking a discovered
|
|
peer opens a direct-message pane; messages use the C-only sealed Cesspool
|
|
record and can be exchanged between Cable-enabled dat-thang clients.
|
|
- `cable-thang` is a native C/S7 room client. Cesspool handles discovery and
|
|
authenticated transport, Sleep persists local feeds, and S7 builds signed
|
|
room-event S-expressions. The room UI supports room creation, named
|
|
channels, nickname changes, and channel cycling. This path is Cable's own
|
|
protocol and does not claim Cabal wire interoperability.
|
|
|
|
### Hypercore feed storage check
|
|
|
|
The test-only Cable compatibility writer occupies the `room/0` slot used by Cabal Core 5's
|
|
`multifeed`, exposes the expected `localname`, and shares the Hypercore tree,
|
|
signature, bitfield, key, and data files. Run
|
|
`tests/interop/dat/cable_hypercore_compat.ps1` on Windows with WSL and Node installed. It
|
|
writes Cabal-shaped nick and chat JSON blocks from C, opens and verifies them
|
|
with the bundled Hypercore 7.7.1, appends a JavaScript block, then confirms C
|
|
reads that appended block. This verifies the standalone C feed format against
|
|
the legacy Hypercore fixture. It is separate from the native Sleep feeds used
|
|
by cable-thang.
|
|
|
|
## Side-by-side regression harness
|
|
|
|
`tests/interop/cabal/cabal_cable_side_by_side.js` creates a Cabal JS room, publishes a nick
|
|
and `chat/text` entry, and verifies that a second Cabal JS instance receives
|
|
both through Cabal's live replication stream. It then gives Cable that exact
|
|
room address, including `?admin=`, checks address normalization, and checks
|
|
that Cable's local user address persists in the room and changes for a second
|
|
room. This covers address normalization and the CLI's local identity utility;
|
|
it does not exercise cable-thang's network session.
|
|
|
|
`tests/interop/cabal/cabal_cli_features.js` uses cabal-cli's own `cabal-client` API to create
|
|
a room, execute `/nick` and `/join`, traverse joined channels using the same
|
|
channel ordering as the CLI's `Ctrl+N` handler, and exchange chat/text entries
|
|
between two independently opened Cabal clients over live Hypercore replication.
|
|
The C SDL live harness is `tests/interop/cabal/cable_js_c_live.js`; it launches one Cabal
|
|
Core JavaScript peer and one headless SDL/C client, then checks peer discovery
|
|
and chat in both directions through the Cabal Hypercore feeds. Run it with
|
|
`make test-cable-live ENABLE_SDL2=1` after building SDL2 support and installing
|
|
Node.js and Cabal Core. The test uses a local Hyperswarm DHT bootstrap node and
|
|
separate client UDP ports.
|
|
|
|
Run it once the historical JS `cabal-core` package and Node are available. The
|
|
test invokes Cabal JS directly; the UI command for people is `cabal-cli`:
|
|
|
|
```sh
|
|
make test-cabal-interop CABAL_JS_MODULE=/path/to/cabal-cli/node_modules/cabal-core
|
|
make test-cabal-interop CABAL_CLIENT_MODULE=/path/to/cabal-cli/node_modules/cabal-client
|
|
```
|
|
|
|
On Windows with Cable built in WSL, run the same harness with Windows Node and
|
|
the installed Cabal package, routing each Cable CLI call through WSL:
|
|
|
|
```powershell
|
|
$env:CABAL_JS_MODULE = "$env:APPDATA\npm\node_modules\cabal-cli\node_modules\cabal-core"
|
|
$env:CABLE_BIN = "$PWD\build\cable"
|
|
$env:CABLE_RUNNER = 'wsl'
|
|
node tests/interop/cabal/cabal_cable_side_by_side.js
|
|
```
|
|
|
|
The harness maps its temporary Cable home directory into WSL for this mode.
|
|
This is useful when the WSL distribution has no Node installation; no second
|
|
Node runtime is needed.
|
|
|
|
The normal `make test` runs this harness when it can resolve `cabal-core`; it
|
|
prints `SKIP` when the configured Node runtime cannot resolve the optional JS
|
|
package. A standalone `make test-cabal-interop` reports the resolution error
|
|
directly.
|
|
|
|
## Compatibility boundary
|
|
|
|
The upstream Cabal components documented here use Hypercore feed replication
|
|
and their own Cabal database/index conventions. Cable's current GUI messages
|
|
use a Cesspool transport record and do not enter Cabal feeds, so they are not
|
|
yet readable by Cabal JS clients. `/nick` in Cabal appends a `{ type: "about",
|
|
content: { name: nick } }` record to the user's room feed; the public user-feed
|
|
key remains its unique identity. Cable has not yet implemented that nickname
|
|
record in the Cabal message schema.
|
|
The next compatibility layer needs the Hypercore transport/session selected
|
|
for the deployed Cabal version, feed discovery, Cabal's multiwriter user-feed
|
|
model, and its JSON message/index schema. Dat archive wire identifiers and
|
|
`dat://` handling remain independent.
|