Skip to content
go-libfossil Changes To go-libfossil
Login

Changes To go-libfossil

Initial version of "go-libfossil"
































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# go-libfossil

Pure Go library for working with Fossil SCM repositories. No CGo, no external dependencies beyond `modernc.org/sqlite`.

## Packages

| Package | Purpose | Key API |
|---------|---------|---------|
| root | Types, julian, errors | `FslID`, `TimeToJulian()`, `JulianToTime()` |
| `db/` | SQLite wrapper | `DB`, `Tx`, `Querier`, `WithTx()` |
| `hash/` | Content addressing | `SHA1()`, `SHA3()` |
| `delta/` | Fossil delta codec | `Create()`, `Apply()` |
| `blob/` | Blob storage | `Store()`, `Load()`, `Exists()` |
| `content/` | Delta chain expansion | `Expand()`, `Verify()` |
| `repo/` | Repo lifecycle | `Create()`, `Open()`, `DB()`, `WithTx()` |
| `testutil/` | Fossil CLI oracle | `HasFossil()`, `FossilRebuild()` |
| `deck/` | Manifest format (no DB) | `Parse()`, `Marshal()`, `ComputeR()`, `VerifyZ()` |
| `manifest/` | Checkin operations | `Checkin()`, `GetManifest()`, `ListFiles()`, `Log()` |
| `xfer/` | Sync wire format (no DB) | `EncodeCard()`, `DecodeCard()`, `Message.Encode/Decode()` |
| `sync/` | Sync engine | `Sync()`, `Transport` interface, `HTTPTransport` |

## Architecture

```
types/errors/julian
    ↓
db → hash → delta → blob → content → repo
                                        ↓
deck → manifest (uses blob, content, repo)
  ↓
xfer (wire format, no DB)
  ↓
sync (ties xfer + storage, Transport interface)
```

## Transport Interface

The sync engine is transport-agnostic via the `Transport` interface:

```go
type Transport interface {
    Exchange(ctx context.Context, request *xfer.Message) (*xfer.Message, error)
}
```

Built-in implementations: `HTTPTransport` (talks to fossil server), `MockTransport` (testing).
External: `NATSTransport` (in the [edgesync](https://fossil.craftdesign.group/edgesync) leaf agent).

## Protocol Details

- Fossil's `blob_compress` uses a 4-byte big-endian size prefix before zlib data
- `HTTPTransport` POSTs to the repo root URL — Fossil routes by `Content-Type: application/x-fossil`
- All 19 xfer card types supported (file, cfile, igot, gimme, login, push, pull, cookie, clone, clone_seqno, config, reqconfig, private, uvfile, uvgimme, uvigot, pragma, error, message)

## Performance (Apple M4 Pro)

| Operation | Time |
|-----------|------|
| Checkin (10 files) | 2.5ms |
| ListFiles (50 files) | 52us |
| Deck Marshal (50 cards) | 8.4us |
| Xfer Message Encode (50 cards) | 62us |
| Full sync round-trip | ~150ms |