diff --git a/eventstore/cmd/eventstore/README.md b/eventstore/cmd/eventstore/README.md index 2b31299..c75463e 100644 --- a/eventstore/cmd/eventstore/README.md +++ b/eventstore/cmd/eventstore/README.md @@ -16,7 +16,7 @@ This should be pretty straightforward. You pipe events or filters, as JSON, to t ~> echo '{"kinds":[1],"limit":100}' | eventstore -d /path/to/store query ``` -This will automatically determine the storage type being used at `/path/to/store`, but you can also specify it manually using the `-t` option (`-t lmdb`, `-t sqlite` etc). +This will automatically determine the storage type being used at `/path/to/store`, but you can also specify it manually using the `-t` option (`-t lmdb` etc). ### Saving an event to the store @@ -26,7 +26,7 @@ This will automatically determine the storage type being used at `/path/to/store ~> echo '{"id":"35369e6bae5f77c4e1745c2eb5db84c4493e87f6e449aee62a261bbc1fea2788","pubkey":"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","created_at":1701193836,"kind":1,"tags":[],"content":"hello","sig":"ef08d559e042d9af4cdc3328a064f737603d86ec4f929f193d5a3ce9ea22a3fb8afc1923ee3c3742fd01856065352c5632e91f633528c80e9c5711fa1266824c"}' | eventstore -d /path/to/store save ``` -You can also create a database from scratch if it's a disk database, but then you have to specify `-t` to `sqlite`, `badger` or `lmdb`. +You can also create a database from scratch if it's a disk database, but then you have to specify `-t` to `boltdb` or `lmdb`. ### Connecting to Postgres, MySQL and other remote databases diff --git a/go.mod b/go.mod index 81b4ab7..b62f3d3 100644 --- a/go.mod +++ b/go.mod @@ -13,8 +13,6 @@ require ( github.com/btcsuite/btcd/btcutil v1.1.5 github.com/coder/websocket v1.8.13 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 - github.com/dgraph-io/badger/v4 v4.5.0 - github.com/dgraph-io/ristretto v1.0.0 github.com/elnosh/gonuts v0.4.2 github.com/fasthttp/websocket v1.5.12 github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62 @@ -34,14 +32,16 @@ require ( github.com/urfave/cli/v3 v3.0.0-beta1 github.com/valyala/fasthttp v1.59.0 go.etcd.io/bbolt v1.4.2 - golang.org/x/crypto v0.36.0 + golang.org/x/crypto v0.39.0 golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 - golang.org/x/net v0.37.0 - golang.org/x/sync v0.12.0 - golang.org/x/text v0.23.0 + golang.org/x/net v0.41.0 + golang.org/x/sync v0.15.0 + golang.org/x/text v0.26.0 gopkg.in/yaml.v3 v3.0.1 ) +require github.com/dgraph-io/ristretto v0.2.0 + require ( github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect @@ -64,13 +64,13 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect - github.com/dgraph-io/ristretto/v2 v2.1.0 // indirect + github.com/dgraph-io/ristretto/v2 v2.3.0 // indirect + github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/snappy v0.0.4 // indirect - github.com/google/flatbuffers v24.12.23+incompatible // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.18.0 // indirect @@ -82,14 +82,12 @@ require ( github.com/mschoch/smat v0.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect github.com/segmentio/asm v1.1.3 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opencensus.io v0.24.0 // indirect - golang.org/x/sys v0.34.0 // indirect - google.golang.org/protobuf v1.36.2 // indirect + golang.org/x/sys v0.35.0 // indirect ) diff --git a/go.sum b/go.sum index 7f0997d..03ff56d 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc= github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw= @@ -86,15 +85,12 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/caio/go-tdigest v3.1.0+incompatible h1:uoVMJ3Q5lXmVLCCqaMGHLBWnbGoN6Lpu7OAUPR60cds= github.com/caio/go-tdigest v3.1.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8q9GjDajLC5T7ydxE3JHI= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE= github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -114,14 +110,12 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeC github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/dgraph-io/badger/v4 v4.5.0 h1:TeJE3I1pIWLBjYhIYCA1+uxrjWEoJXImFBMEBVSm16g= -github.com/dgraph-io/badger/v4 v4.5.0/go.mod h1:ysgYmIeG8dS/E8kwxT7xHyc7MkmwNYLRoYnFbr7387A= -github.com/dgraph-io/ristretto v1.0.0 h1:SYG07bONKMlFDUYu5pEu3DGAh8c2OFNzKm6G9J4Si84= -github.com/dgraph-io/ristretto v1.0.0/go.mod h1:jTi2FiYEhQ1NsMmA7DeBykizjOuY88NhKBkepyu1jPc= -github.com/dgraph-io/ristretto/v2 v2.1.0 h1:59LjpOJLNDULHh8MC4UaegN52lC4JnO2dITsie/Pa8I= -github.com/dgraph-io/ristretto/v2 v2.1.0/go.mod h1:uejeqfYXpUomfse0+lO+13ATz4TypQYLJZzBSAemuB4= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE= +github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU= +github.com/dgraph-io/ristretto/v2 v2.3.0 h1:qTQ38m7oIyd4GAed/QkUZyPFNMnvVWyazGXRwvOt5zk= +github.com/dgraph-io/ristretto/v2 v2.3.0/go.mod h1:gpoRV3VzrEY1a9dWAYV6T1U7YzfgttXdd/ZzL1s9OZM= +github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38= +github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0= github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= @@ -130,10 +124,6 @@ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+m github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/elnosh/gonuts v0.4.2 h1:/WubPAWGxTE+okJ0WPvmtEzTzpi04RGxiTHAF1FYU+M= github.com/elnosh/gonuts v0.4.2/go.mod h1:vgZomh4YQk7R3w4ltZc0sHwCmndfHkuX6V4sga/8oNs= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fasthttp/websocket v1.5.12 h1:e4RGPpWW2HTbL3zV0Y/t7g0ub294LkiuXXUuTOUInlE= github.com/fasthttp/websocket v1.5.12/go.mod h1:I+liyL7/4moHojiOgUOIKEWm9EIxHqxZChS+aMFltyg= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= @@ -143,38 +133,24 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62 h1:pbAFUZisjG4s6sxvRJvf2N7vhpCvx2Oxb3PmS6pDO1g= github.com/gomarkdown/markdown v0.0.0-20241205020045-f7e15b2f3e62/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= -github.com/google/flatbuffers v24.12.23+incompatible h1:ubBKR94NR4pXUCY/MUsRVzd9umNW7ht7EG9hHfS9FX8= -github.com/google/flatbuffers v24.12.23+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -237,12 +213,11 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg= github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -263,17 +238,12 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= @@ -302,44 +272,29 @@ github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZ github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I= go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= -golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -352,25 +307,22 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= @@ -378,27 +330,12 @@ gonum.org/v1/gonum v0.7.0 h1:Hdks0L0hgznZLG9nzXb8vZ0rRvqNvAcgAp84y7Mwkgw= gonum.org/v1/gonum v0.7.0/go.mod h1:L02bwd0sqlsvRv41G7wGWFCsVNZFv/k1xzGIxeANHGM= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= -google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -413,8 +350,6 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/khatru/docs/core/blossom.md b/khatru/docs/core/blossom.md index ea950b8..0445882 100644 --- a/khatru/docs/core/blossom.md +++ b/khatru/docs/core/blossom.md @@ -105,7 +105,7 @@ There are other `Reject*` hooks you can also implement, but this is the most imp Blossom needs a database to keep track of blob metadata in order to know which user owns each blob, for example (and mind you that more than one user might own the same blob so when of them deletes the blob we don't actually delete it because the other user still has a claim to it). The simplest way to do it currently is by relying on a wrapper on top of fake Nostr events over eventstore, which is `EventStoreBlobIndexWrapper`, but other solutions can be used. ```go -db := &badger.BadgerBackend{Path: "/tmp/khatru-badger-blossom-blobstore"} +db := &boltdb.BoltBackend{Path: "/tmp/khatru-bolt-blossom-blobstore"} db.Init() bl.Store = blossom.EventStoreBlobIndexWrapper{ diff --git a/khatru/docs/core/eventstore.md b/khatru/docs/core/eventstore.md index dd329ea..de4e184 100644 --- a/khatru/docs/core/eventstore.md +++ b/khatru/docs/core/eventstore.md @@ -14,7 +14,7 @@ The library includes many different adapters -- often called "backends" --, writ For all of them you start by instantiating a struct containing some basic options and a pointer (a file path for local databases, a connection string for remote databases) to the data. Then you call `.Init()` and if all is well you're ready to start storing, querying and deleting events, so you can pass the respective functions to their `khatru` counterparts. These eventstores also expose a `.Close()` function that must be called if you're going to stop using that store and keep your application open. -Here's an example with the [Badger](https://pkg.go.dev/fiatjaf.com/nostr/eventstore/badger) adapter, made for the [Badger](https://github.com/dgraph-io/badger) embedded key-value database: +Here's an example with the [BoltDB](https://pkg.go.dev/fiatjaf.com/nostr/eventstore/boltdb) adapter, made for the [BoltDB](https://github.com/etcd-io/bbolt) embedded key-value database: ```go package main @@ -23,14 +23,14 @@ import ( "fmt" "net/http" - "fiatjaf.com/nostr/eventstore/badger" + "fiatjaf.com/nostr/eventstore/boltdb" "fiatjaf.com/nostr/khatru" ) func main() { relay := khatru.NewRelay() - db := badger.BadgerBackend{Path: "/tmp/khatru-badger-tmp"} + db := boltdb.BoltBackend{Path: "/tmp/khatru-bolt-tmp"} if err := db.Init(); err != nil { panic(err) } diff --git a/khatru/docs/core/routing.md b/khatru/docs/core/routing.md index 9c6de54..e79d044 100644 --- a/khatru/docs/core/routing.md +++ b/khatru/docs/core/routing.md @@ -12,7 +12,7 @@ It also can be handy if you get a [`khatru.Relay`](https://pkg.go.dev/github.com sk := os.Getenv("RELAY_SECRET_KEY") // a relay for NIP-29 groups -groupsStore := badger.BadgerBackend{} +groupsStore := boltdb.BoltBackend{} groupsStore.Init() groupsRelay, _ := khatru29.Init(relay29.Options{Domain: "example.com", DB: groupsStore, SecretKey: sk}) // ... diff --git a/khatru/docs/getting-started/index.md b/khatru/docs/getting-started/index.md index d042a9c..a6d5c6c 100644 --- a/khatru/docs/getting-started/index.md +++ b/khatru/docs/getting-started/index.md @@ -31,10 +31,10 @@ relay.Info.Description = "this is my custom relay" relay.Info.Icon = "https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fliquipedia.net%2Fcommons%2Fimages%2F3%2F35%2FSCProbe.jpg&f=1&nofb=1&ipt=0cbbfef25bce41da63d910e86c3c343e6c3b9d63194ca9755351bb7c2efa3359&ipo=images" ``` -Now we must set up the basic functions for accepting events and answering queries. We could make our own querying engine from scratch, but we can also use [eventstore](https://pkg.go.dev/fiatjaf.com/nostr/eventstore). In this example we'll use the Badger adapter: +Now we must set up the basic functions for accepting events and answering queries. We could make our own querying engine from scratch, but we can also use [eventstore](https://pkg.go.dev/fiatjaf.com/nostr/eventstore). In this example we'll use the BoltDB adapter: ```go -db := badger.BadgerBackend{Path: "/tmp/khatru-badger-tmp"} +db := boltdb.BoltBackend{Path: "/tmp/khatru-bolt-tmp"} if err := db.Init(); err != nil { panic(err) } diff --git a/khatru/docs/index.md b/khatru/docs/index.md index 18af66f..8446fac 100644 --- a/khatru/docs/index.md +++ b/khatru/docs/index.md @@ -24,7 +24,7 @@ features: - title: It plugs into event stores easily icon: 📦 link: /core/eventstore - details: khatru's companion, the `eventstore` library, provides all methods for storing and querying events efficiently from LMDB, Badger and others. + details: khatru's companion, the `eventstore` library, provides all methods for storing and querying events efficiently from LMDB, BoltDB and others. - title: It supports NIP-42 AUTH icon: 🪪 link: /core/auth @@ -46,7 +46,7 @@ It allows you to create a fully-functional relay in 7 lines of code: ```go func main() { relay := khatru.NewRelay() - db := badger.BadgerBackend{Path: "/tmp/khatru-badgern-tmp"} + db := boltdb.BoltBackend{Path: "/tmp/khatru-bolt-tmp"} db.Init() relay.UseEventStore(db, 400) http.ListenAndServe(":3334", relay) diff --git a/sdk/cache/memory/cache.go b/sdk/cache/memory/cache.go index 97d1cac..233eaf6 100644 --- a/sdk/cache/memory/cache.go +++ b/sdk/cache/memory/cache.go @@ -4,7 +4,7 @@ import ( "encoding/binary" "time" - "github.com/dgraph-io/ristretto" + "github.com/dgraph-io/ristretto/v2" ) type RistrettoCache[V any] struct { diff --git a/sdk/hints/badgerh/db.go b/sdk/hints/badgerh/db.go deleted file mode 100644 index 7e35797..0000000 --- a/sdk/hints/badgerh/db.go +++ /dev/null @@ -1,220 +0,0 @@ -package badgerh - -import ( - "fmt" - "math" - "slices" - - "fiatjaf.com/nostr" - "fiatjaf.com/nostr/sdk/hints" - "github.com/dgraph-io/badger/v4" -) - -var _ hints.HintsDB = (*BadgerHints)(nil) - -type BadgerHints struct { - db *badger.DB -} - -func NewBadgerHints(path string) (*BadgerHints, error) { - opts := badger.DefaultOptions(path) - opts.Logger = nil - db, err := badger.Open(opts) - if err != nil { - return nil, fmt.Errorf("failed to open badger db: %w", err) - } - return &BadgerHints{db: db}, nil -} - -func (bh *BadgerHints) Close() { - bh.db.Close() -} - -func (bh *BadgerHints) Save(pubkey nostr.PubKey, relay string, hintkey hints.HintKey, ts nostr.Timestamp) { - if now := nostr.Now(); ts > now { - ts = now - } - - err := bh.db.Update(func(txn *badger.Txn) error { - k := encodeKey(pubkey, relay) - var tss timestamps - item, err := txn.Get(k) - if err == nil { - err = item.Value(func(val []byte) error { - // there is a value, so we may update it or not - tss = parseValue(val) - return nil - }) - if err != nil { - return err - } - } else if err != badger.ErrKeyNotFound { - return err - } - - if tss[hintkey] < ts { - tss[hintkey] = ts - return txn.Set(k, encodeValue(tss)) - } - - return nil - }) - if err != nil { - nostr.InfoLogger.Printf("[sdk/hints/badger] unexpected error on save: %s\n", err) - } -} - -func (bh *BadgerHints) TopN(pubkey nostr.PubKey, n int) []string { - type relayScore struct { - relay string - score int64 - } - - scores := make([]relayScore, 0, n) - err := bh.db.View(func(txn *badger.Txn) error { - opts := badger.DefaultIteratorOptions - opts.Prefix = pubkey[:] - it := txn.NewIterator(opts) - defer it.Close() - - for it.Seek(opts.Prefix); it.Valid(); it.Next() { - item := it.Item() - k := item.Key() - relay := string(k[32:]) - - err := item.Value(func(val []byte) error { - tss := parseValue(val) - scores = append(scores, relayScore{relay, tss.sum()}) - return nil - }) - if err != nil { - continue - } - } - return nil - }) - if err != nil { - nostr.InfoLogger.Printf("[sdk/hints/badger] unexpected error on topn: %s\n", err) - return nil - } - - slices.SortFunc(scores, func(a, b relayScore) int { - return int(b.score - a.score) - }) - - result := make([]string, 0, n) - for i, rs := range scores { - if i >= n { - break - } - result = append(result, rs.relay) - } - return result -} - -func (bh *BadgerHints) GetDetailedScores(pubkey nostr.PubKey, n int) []hints.RelayScores { - type relayScore struct { - relay string - tss timestamps - score int64 - } - - scores := make([]relayScore, 0, n) - err := bh.db.View(func(txn *badger.Txn) error { - it := txn.NewIterator(badger.DefaultIteratorOptions) - defer it.Close() - - for it.Seek(pubkey[:]); it.ValidForPrefix(pubkey[:]); it.Next() { - item := it.Item() - k := item.Key() - relay := string(k[32:]) - - var tss timestamps - err := item.Value(func(v []byte) error { - tss = parseValue(v) - return nil - }) - if err != nil { - return err - } - - scores = append(scores, relayScore{relay, tss, tss.sum()}) - } - return nil - }) - if err != nil { - return nil - } - - slices.SortFunc(scores, func(a, b relayScore) int { - return int(b.score - a.score) - }) - - result := make([]hints.RelayScores, 0, n) - for i, rs := range scores { - if i >= n { - break - } - result = append(result, hints.RelayScores{ - Relay: rs.relay, - Scores: rs.tss, - Sum: rs.score, - }) - } - return result -} - -func (bh *BadgerHints) PrintScores() { - fmt.Println("= print scores") - - err := bh.db.View(func(txn *badger.Txn) error { - it := txn.NewIterator(badger.DefaultIteratorOptions) - defer it.Close() - - var lastPubkey nostr.PubKey - i := 0 - - for it.Seek(nil); it.Valid(); it.Next() { - item := it.Item() - k := item.Key() - pubkey, relay := parseKey(k) - - if pubkey != lastPubkey { - fmt.Println("== relay scores for", pubkey) - lastPubkey = pubkey - i = 0 - } else { - i++ - } - - err := item.Value(func(val []byte) error { - tss := parseValue(val) - fmt.Printf(" %3d :: %30s ::> %12d\n", i, relay, tss.sum()) - return nil - }) - if err != nil { - continue - } - } - return nil - }) - if err != nil { - nostr.InfoLogger.Printf("[sdk/hints/badger] unexpected error on print: %s\n", err) - } -} - -type timestamps [4]nostr.Timestamp - -func (tss timestamps) sum() int64 { - now := nostr.Now() + 24*60*60 - var sum int64 - for i, ts := range tss { - if ts == 0 { - continue - } - value := float64(hints.HintKey(i).BasePoints()) * 10000000000 / math.Pow(float64(max(now-ts, 1)), 1.3) - // fmt.Println(" ", i, "value:", value) - sum += int64(value) - } - return sum -} diff --git a/sdk/hints/bbolth/db.go b/sdk/hints/bbolth/db.go new file mode 100644 index 0000000..039c864 --- /dev/null +++ b/sdk/hints/bbolth/db.go @@ -0,0 +1,196 @@ +package bbolth + +import ( + "fmt" + "math" + "slices" + + "fiatjaf.com/nostr" + "fiatjaf.com/nostr/sdk/hints" + "go.etcd.io/bbolt" +) + +var _ hints.HintsDB = (*BoltHints)(nil) + +var ( + hintsBucket = []byte("hints") +) + +type BoltHints struct { + db *bbolt.DB +} + +func NewBoltHints(path string) (*BoltHints, error) { + db, err := bbolt.Open(path, 0600, nil) + if err != nil { + return nil, fmt.Errorf("failed to open bbolt db: %w", err) + } + + // Create the hints bucket + err = db.Update(func(tx *bbolt.Tx) error { + _, err := tx.CreateBucketIfNotExists(hintsBucket) + return err + }) + if err != nil { + db.Close() + return nil, err + } + + return &BoltHints{db: db}, nil +} + +func (bh *BoltHints) Close() { + bh.db.Close() +} + +func (bh *BoltHints) Save(pubkey nostr.PubKey, relay string, hintkey hints.HintKey, ts nostr.Timestamp) { + if now := nostr.Now(); ts > now { + ts = now + } + + err := bh.db.Update(func(tx *bbolt.Tx) error { + b := tx.Bucket(hintsBucket) + k := encodeKey(pubkey, relay) + var tss timestamps + + if v := b.Get(k); v != nil { + tss = parseValue(v) + } + + if tss[hintkey] < ts { + tss[hintkey] = ts + return b.Put(k, encodeValue(tss)) + } + + return nil + }) + if err != nil { + nostr.InfoLogger.Printf("[sdk/hints/bbolt] unexpected error on save: %s\n", err) + } +} + +func (bh *BoltHints) TopN(pubkey nostr.PubKey, n int) []string { + type relayScore struct { + relay string + score int64 + } + + scores := make([]relayScore, 0, n) + err := bh.db.View(func(tx *bbolt.Tx) error { + b := tx.Bucket(hintsBucket) + c := b.Cursor() + + prefix := pubkey[:] + for k, v := c.Seek(prefix); k != nil && len(k) >= 32 && string(k[:32]) == string(prefix); k, v = c.Next() { + relay := string(k[32:]) + tss := parseValue(v) + scores = append(scores, relayScore{relay, tss.sum()}) + } + return nil + }) + if err != nil { + nostr.InfoLogger.Printf("[sdk/hints/bbolt] unexpected error on topn: %s\n", err) + return nil + } + + slices.SortFunc(scores, func(a, b relayScore) int { + return int(b.score - a.score) + }) + + result := make([]string, 0, n) + for i, rs := range scores { + if i >= n { + break + } + result = append(result, rs.relay) + } + return result +} + +func (bh *BoltHints) GetDetailedScores(pubkey nostr.PubKey, n int) []hints.RelayScores { + type relayScore struct { + relay string + tss timestamps + score int64 + } + + scores := make([]relayScore, 0, n) + err := bh.db.View(func(tx *bbolt.Tx) error { + b := tx.Bucket(hintsBucket) + c := b.Cursor() + + prefix := pubkey[:] + for k, v := c.Seek(prefix); k != nil && len(k) >= 32 && string(k[:32]) == string(prefix); k, v = c.Next() { + relay := string(k[32:]) + tss := parseValue(v) + scores = append(scores, relayScore{relay, tss, tss.sum()}) + } + return nil + }) + if err != nil { + return nil + } + + slices.SortFunc(scores, func(a, b relayScore) int { + return int(b.score - a.score) + }) + + result := make([]hints.RelayScores, 0, n) + for i, rs := range scores { + if i >= n { + break + } + result = append(result, hints.RelayScores{ + Relay: rs.relay, + Scores: rs.tss, + Sum: rs.score, + }) + } + return result +} + +func (bh *BoltHints) PrintScores() { + fmt.Println("= print scores") + + err := bh.db.View(func(tx *bbolt.Tx) error { + b := tx.Bucket(hintsBucket) + c := b.Cursor() + + var lastPubkey nostr.PubKey + i := 0 + + for k, v := c.First(); k != nil; k, v = c.Next() { + pubkey, relay := parseKey(k) + tss := parseValue(v) + + if pubkey != lastPubkey { + fmt.Println("== relay scores for", pubkey) + lastPubkey = pubkey + i = 0 + } else { + i++ + } + + fmt.Printf(" %3d :: %30s ::> %12d\n", i, relay, tss.sum()) + } + return nil + }) + if err != nil { + nostr.InfoLogger.Printf("[sdk/hints/bbolt] unexpected error on print: %s\n", err) + } +} + +type timestamps [4]nostr.Timestamp + +func (tss timestamps) sum() int64 { + now := nostr.Now() + 24*60*60 + var sum int64 + for i, ts := range tss { + if ts == 0 { + continue + } + value := float64(hints.HintKey(i).BasePoints()) * 10000000000 / math.Pow(float64(max(now-ts, 1)), 1.3) + sum += int64(value) + } + return sum +} diff --git a/sdk/hints/badgerh/keys.go b/sdk/hints/bbolth/keys.go similarity index 88% rename from sdk/hints/badgerh/keys.go rename to sdk/hints/bbolth/keys.go index 077c971..e9bfdc7 100644 --- a/sdk/hints/badgerh/keys.go +++ b/sdk/hints/bbolth/keys.go @@ -1,4 +1,4 @@ -package badgerh +package bbolth import ( "encoding/binary" @@ -6,9 +6,9 @@ import ( "fiatjaf.com/nostr" ) -func encodeKey(pubhintkey nostr.PubKey, relay string) []byte { +func encodeKey(pubkey nostr.PubKey, relay string) []byte { k := make([]byte, 32+len(relay)) - copy(k[0:32], pubhintkey[:]) + copy(k[0:32], pubkey[:]) copy(k[32:], relay) return k } diff --git a/sdk/hints/test/badger_test.go b/sdk/hints/test/badger_test.go deleted file mode 100644 index 3caf735..0000000 --- a/sdk/hints/test/badger_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package test - -import ( - "os" - "testing" - - "fiatjaf.com/nostr/sdk/hints/badgerh" -) - -func TestBadgerHints(t *testing.T) { - path := "/tmp/tmpsdkhintsbadger" - os.RemoveAll(path) - - hdb, err := badgerh.NewBadgerHints(path) - if err != nil { - t.Fatal(err) - } - defer hdb.Close() - - runTestWith(t, hdb) -} diff --git a/sdk/hints/test/bbolt_test.go b/sdk/hints/test/bbolt_test.go new file mode 100644 index 0000000..9fa0f8e --- /dev/null +++ b/sdk/hints/test/bbolt_test.go @@ -0,0 +1,21 @@ +package test + +import ( + "os" + "testing" + + "fiatjaf.com/nostr/sdk/hints/bbolth" +) + +func TestBoltHints(t *testing.T) { + path := "/tmp/tmpsdkhintsbbolt" + os.RemoveAll(path) + + hdb, err := bbolth.NewBoltHints(path) + if err != nil { + t.Fatal(err) + } + defer hdb.Close() + + runTestWith(t, hdb) +} diff --git a/sdk/kvstore/badger/store.go b/sdk/kvstore/badger/store.go deleted file mode 100644 index 064a2ac..0000000 --- a/sdk/kvstore/badger/store.go +++ /dev/null @@ -1,90 +0,0 @@ -package badger - -import ( - "github.com/dgraph-io/badger/v4" - "fiatjaf.com/nostr/sdk/kvstore" -) - -var _ kvstore.KVStore = (*Store)(nil) - -type Store struct { - db *badger.DB -} - -func NewStore(path string) (*Store, error) { - opts := badger.DefaultOptions(path) - db, err := badger.Open(opts) - if err != nil { - return nil, err - } - return &Store{db: db}, nil -} - -func (s *Store) Get(key []byte) ([]byte, error) { - var valCopy []byte - err := s.db.View(func(txn *badger.Txn) error { - item, err := txn.Get(key) - if err == badger.ErrKeyNotFound { - return nil - } - if err != nil { - return err - } - return item.Value(func(val []byte) error { - valCopy = make([]byte, len(val)) - copy(valCopy, val) - return nil - }) - }) - if err != nil { - return nil, err - } - return valCopy, nil -} - -func (s *Store) Set(key []byte, value []byte) error { - return s.db.Update(func(txn *badger.Txn) error { - return txn.Set(key, value) - }) -} - -func (s *Store) Delete(key []byte) error { - return s.db.Update(func(txn *badger.Txn) error { - return txn.Delete(key) - }) -} - -func (s *Store) Close() error { - return s.db.Close() -} - -func (s *Store) Update(key []byte, f func([]byte) ([]byte, error)) error { - return s.db.Update(func(txn *badger.Txn) error { - var val []byte - item, err := txn.Get(key) - if err == nil { - err = item.Value(func(v []byte) error { - val = make([]byte, len(v)) - copy(val, v) - return nil - }) - if err != nil { - return err - } - } else if err != badger.ErrKeyNotFound { - return err - } - - newVal, err := f(val) - if err == kvstore.NoOp { - return nil - } else if err != nil { - return err - } - - if newVal == nil { - return txn.Delete(key) - } - return txn.Set(key, newVal) - }) -} diff --git a/sdk/kvstore/bbolt/store.go b/sdk/kvstore/bbolt/store.go new file mode 100644 index 0000000..1e49f5f --- /dev/null +++ b/sdk/kvstore/bbolt/store.go @@ -0,0 +1,96 @@ +package bbolt + +import ( + "fiatjaf.com/nostr/sdk/kvstore" + "go.etcd.io/bbolt" +) + +var _ kvstore.KVStore = (*Store)(nil) + +var ( + defaultBucket = []byte("default") +) + +type Store struct { + db *bbolt.DB + bucket []byte +} + +func NewStore(path string) (*Store, error) { + db, err := bbolt.Open(path, 0600, nil) + if err != nil { + return nil, err + } + + // Create the default bucket + err = db.Update(func(tx *bbolt.Tx) error { + _, err := tx.CreateBucketIfNotExists(defaultBucket) + return err + }) + if err != nil { + db.Close() + return nil, err + } + + return &Store{db: db, bucket: defaultBucket}, nil +} + +func (s *Store) Get(key []byte) ([]byte, error) { + var val []byte + err := s.db.View(func(tx *bbolt.Tx) error { + b := tx.Bucket(s.bucket) + if b == nil { + return nil + } + val = b.Get(key) + if val != nil { + // Make a copy since bbolt reuses the slice + valCopy := make([]byte, len(val)) + copy(valCopy, val) + val = valCopy + } + return nil + }) + return val, err +} + +func (s *Store) Set(key []byte, value []byte) error { + return s.db.Update(func(tx *bbolt.Tx) error { + b := tx.Bucket(s.bucket) + return b.Put(key, value) + }) +} + +func (s *Store) Delete(key []byte) error { + return s.db.Update(func(tx *bbolt.Tx) error { + b := tx.Bucket(s.bucket) + return b.Delete(key) + }) +} + +func (s *Store) Close() error { + return s.db.Close() +} + +func (s *Store) Update(key []byte, f func([]byte) ([]byte, error)) error { + return s.db.Update(func(tx *bbolt.Tx) error { + b := tx.Bucket(s.bucket) + var val []byte + if v := b.Get(key); v != nil { + val = make([]byte, len(v)) + copy(val, v) + } + + newVal, err := f(val) + if err == kvstore.NoOp { + return nil + } else if err != nil { + return err + } + + if newVal == nil { + return b.Delete(key) + } + return b.Put(key, newVal) + }) +}