From 9d181afceb912660d638034aff1b35d91a6c2cf3 Mon Sep 17 00:00:00 2001 From: Code0987 <1825861+Code0987@users.noreply.github.com> Date: Thu, 8 Oct 2026 10:55:09 +0000 Subject: [PATCH 1/3] feat: add Python and Node Cache clients In-repo clients speak the existing Cache gRPC port. CI regenerates the stubs from cache.proto and fails unless both facades and docs/API.md cover every Cache RPC. --- .github/workflows/ci.yml | 54 + .gitignore | 8 + PLAN.md | 2 +- README.md | 34 + clients/conformance/fixture.go | 140 + clients/conformance/fixture_test.go | 104 + clients/conformance/main.go | 34 + clients/conformance/tls.go | 134 + clients/node/README.md | 69 + clients/node/examples/kv.ts | 16 + clients/node/package-lock.json | 441 + clients/node/package.json | 31 + clients/node/src/client.ts | 670 + clients/node/src/errors.ts | 60 + clients/node/src/gen/cache.ts | 12742 ++++++++++++++++ clients/node/src/index.ts | 27 + clients/node/src/session.ts | 127 + clients/node/src/types.ts | 69 + clients/node/test/client.test.ts | 361 + clients/node/tsconfig.json | 15 + clients/python/README.md | 60 + clients/python/examples/kv.py | 15 + clients/python/pyproject.toml | 19 + clients/python/src/supercache/__init__.py | 49 + .../python/src/supercache/_gen/__init__.py | 1 + .../python/src/supercache/_gen/cache_pb2.py | 307 + .../src/supercache/_gen/cache_pb2_grpc.py | 2809 ++++ clients/python/src/supercache/client.py | 170 + clients/python/src/supercache/errors.py | 69 + clients/python/src/supercache/ops/__init__.py | 1 + clients/python/src/supercache/ops/bitmap.py | 52 + clients/python/src/supercache/ops/bloom.py | 25 + clients/python/src/supercache/ops/cms.py | 35 + clients/python/src/supercache/ops/counter.py | 18 + clients/python/src/supercache/ops/geo.py | 104 + clients/python/src/supercache/ops/hash.py | 52 + clients/python/src/supercache/ops/hll.py | 22 + clients/python/src/supercache/ops/json.py | 36 + clients/python/src/supercache/ops/list.py | 63 + clients/python/src/supercache/ops/set.py | 43 + clients/python/src/supercache/ops/stream.py | 59 + clients/python/src/supercache/ops/topk.py | 23 + clients/python/src/supercache/ops/vecset.py | 81 + clients/python/src/supercache/ops/zset.py | 81 + clients/python/src/supercache/session.py | 131 + clients/python/src/supercache/types.py | 77 + clients/python/src/supercache/wire.py | 50 + clients/python/tests/test_client.py | 336 + docs/API.md | 6 + docs/design/2026-10-08-polyglot-clients.md | 67 + docs/design/README.md | 1 + scripts/check-client-surface.py | 167 + scripts/gen-clients.sh | 70 + 53 files changed, 20236 insertions(+), 1 deletion(-) create mode 100644 clients/conformance/fixture.go create mode 100644 clients/conformance/fixture_test.go create mode 100644 clients/conformance/main.go create mode 100644 clients/conformance/tls.go create mode 100644 clients/node/README.md create mode 100644 clients/node/examples/kv.ts create mode 100644 clients/node/package-lock.json create mode 100644 clients/node/package.json create mode 100644 clients/node/src/client.ts create mode 100644 clients/node/src/errors.ts create mode 100644 clients/node/src/gen/cache.ts create mode 100644 clients/node/src/index.ts create mode 100644 clients/node/src/session.ts create mode 100644 clients/node/src/types.ts create mode 100644 clients/node/test/client.test.ts create mode 100644 clients/node/tsconfig.json create mode 100644 clients/python/README.md create mode 100644 clients/python/examples/kv.py create mode 100644 clients/python/pyproject.toml create mode 100644 clients/python/src/supercache/__init__.py create mode 100644 clients/python/src/supercache/_gen/__init__.py create mode 100644 clients/python/src/supercache/_gen/cache_pb2.py create mode 100644 clients/python/src/supercache/_gen/cache_pb2_grpc.py create mode 100644 clients/python/src/supercache/client.py create mode 100644 clients/python/src/supercache/errors.py create mode 100644 clients/python/src/supercache/ops/__init__.py create mode 100644 clients/python/src/supercache/ops/bitmap.py create mode 100644 clients/python/src/supercache/ops/bloom.py create mode 100644 clients/python/src/supercache/ops/cms.py create mode 100644 clients/python/src/supercache/ops/counter.py create mode 100644 clients/python/src/supercache/ops/geo.py create mode 100644 clients/python/src/supercache/ops/hash.py create mode 100644 clients/python/src/supercache/ops/hll.py create mode 100644 clients/python/src/supercache/ops/json.py create mode 100644 clients/python/src/supercache/ops/list.py create mode 100644 clients/python/src/supercache/ops/set.py create mode 100644 clients/python/src/supercache/ops/stream.py create mode 100644 clients/python/src/supercache/ops/topk.py create mode 100644 clients/python/src/supercache/ops/vecset.py create mode 100644 clients/python/src/supercache/ops/zset.py create mode 100644 clients/python/src/supercache/session.py create mode 100644 clients/python/src/supercache/types.py create mode 100644 clients/python/src/supercache/wire.py create mode 100644 clients/python/tests/test_client.py create mode 100644 docs/design/2026-10-08-polyglot-clients.md create mode 100644 scripts/check-client-surface.py create mode 100644 scripts/gen-clients.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7719553..dc0f04b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,3 +105,57 @@ jobs: tail -n 40 micro.txt 2>/dev/null || true echo '```' } >> "$GITHUB_STEP_SUMMARY" + + # Fails when cache.proto moves and the Python or Node client was not regenerated + # or a facade method was not added. See docs/design/2026-10-08-polyglot-clients.md. + clients-up-to-date: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + - uses: actions/setup-node@v4 + with: + node-version: "22" + - name: Install protoc 28.3 + run: | + curl -fsSL -o /tmp/protoc.zip https://github.com/protocolbuffers/protobuf/releases/download/v28.3/protoc-28.3-linux-x86_64.zip + sudo unzip -o /tmp/protoc.zip -d /usr/local + protoc --version + - name: Install generators + run: | + python3 -m pip install 'grpcio-tools==1.69.0' + npm ci --prefix clients/node + - name: Regenerated stubs match the tree + run: | + bash scripts/gen-clients.sh + git diff --exit-code -- clients/python/src/supercache/_gen clients/node/src/gen + - name: Facades cover every Cache RPC + run: python3 scripts/check-client-surface.py + + clients: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: "1.22.x" + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + - uses: actions/setup-node@v4 + with: + node-version: "22" + - name: Conformance server + run: go test ./clients/conformance/ -count=1 + - name: Python client + run: | + python3 -m pip install -e "./clients/python[dev]" + pytest clients/python/tests -q + - name: Node client + working-directory: clients/node + run: | + npm ci + npm test + npm run build diff --git a/.gitignore b/.gitignore index 6abfc0f..8d91bcb 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,11 @@ Thumbs.db # Python __pycache__/ *.py[cod] +clients/python/*.egg-info/ +clients/python/src/*.egg-info/ +clients/python/.pytest_cache/ +clients/python/.venv/ + +# Node client (stubs under src/gen are committed) +clients/node/node_modules/ +clients/node/dist/ diff --git a/PLAN.md b/PLAN.md index 2a4b88c..701a830 100644 --- a/PLAN.md +++ b/PLAN.md @@ -141,7 +141,7 @@ Owner-only storage + remote Get would scale memory with N but would **break** th | Peer write path | Owner ACK + **async fan-out to R−1 replicas**; peer failures **logged, not retried, not returned** on Put | | Persistence | **None** | | Workload | **Read-heavy** | -| Client API | **gRPC** `Cache` service (KV + Bloom + Set + ZSet) + optional in-process Engine + `cmd/sc` | +| Client API | **gRPC** `Cache` service + in-process Engine + `cmd/sc` + in-repo Python (`clients/python`) and Node (`clients/node`) clients | | Local store | Custom versioned **LRU** (`pkg/store`) with structure caches for set/zset — **not** stock groupcache | | Membership | **hashicorp/memberlist** (gossip); optional `WithGossipSecret` | | Hash ring | Consistent hash with virtual nodes over **cache-node** peers only | diff --git a/README.md b/README.md index debb4ef..46c3d83 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,38 @@ go run ./cmd/sc Install: `go install ./cmd/sc`. See [cmd/sc/README.md](./cmd/sc/README.md). +### Python and Node + +In-repo clients for the Cache port. They are not published. Do not point them at the peer port. + +```bash +# Python 3.11+ +python3 -m venv .venv && . .venv/bin/activate +pip install -e ./clients/python +``` + +```python +import supercache +c = supercache.dial("127.0.0.1:9000") +c.put("cacheonly", "greeting", b"hello") +print(c.get("cacheonly", "greeting")) +c.close() +``` + +```bash +cd clients/node && npm ci && npm run build +``` + +```js +import { dial } from "@code0987/supercache"; +const c = dial("127.0.0.1:9000"); +await c.put("cacheonly", "greeting", "hello"); +console.log(Buffer.from(await c.get("cacheonly", "greeting")).toString()); +c.close(); +``` + +See [clients/python/README.md](./clients/python/README.md) and [clients/node/README.md](./clients/node/README.md). + ### Benchmarks Local SuperCache vs Redis (multi-trial medians): @@ -228,6 +260,8 @@ Apps: `client.DialTLS` with `pkg/tlsconfig.ClientFiles`. See [docs/OPERATIONS.md | `pkg/membership` | Gossip + ring rebuild | | `pkg/warmup` | Hot keys, topology handoff (hot then rest), refresh-ahead | | `pkg/client` | Application gRPC client (KV + Bloom + Set + ZSet + Geo + List + Hash + Counter + JSON + Bitmap + HLL + TopK + CMS + VectorSet + Stream) | +| `clients/python`, `clients/node` | Same Cache contract for Python 3.11+ and Node 22+ | +| `clients/conformance` | Single-node Cache server the language tests dial | | `pkg/tlsconfig` | TLS/mTLS config from PEM files | | `cmd/supercache-node` | Node binary (`-demo-keyspace`: cacheonly / set / zset / hash / json / bitmap / vectorset) | | `cmd/sc` | CLI: get/put/del, bloom, sadd*, z*, geo*, l*, h*, incr/cget, json*, bit*, hlladd/hllcount, topkadd/topklist, cmsincr/cmsquery, vadd*, xadd* | diff --git a/clients/conformance/fixture.go b/clients/conformance/fixture.go new file mode 100644 index 0000000..5361c36 --- /dev/null +++ b/clients/conformance/fixture.go @@ -0,0 +1,140 @@ +// Command conformance is a single-node Cache gRPC server for client SDK tests. +// +// go run ./clients/conformance +// addr=127.0.0.1:12345 +// +// -tls prints PEM paths. -mtls also requires a client certificate. +// The process serves until SIGINT or SIGTERM. Stdout is only the ready lines. +package main + +import ( + "fmt" + "sync" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + + "github.com/Code0987/supercache/internal/cacheserver" + "github.com/Code0987/supercache/pkg/datasource" + "github.com/Code0987/supercache/pkg/engine" + "github.com/Code0987/supercache/pkg/keyspace" + "github.com/Code0987/supercache/pkg/tlsconfig" +) + +// Options selects plaintext or TLS for Listen. +type Options struct { + TLS bool + MTLS bool +} + +// TLSMaterial is the PEM set written for a TLS server. +type TLSMaterial struct { + Dir string + CA string + Cert string + Key string + ClientCert string + ClientKey string +} + +// Server is a running conformance cache. +type Server struct { + Engine *engine.Engine + Addr string + TLS *TLSMaterial + + gs *grpc.Server + once sync.Once +} + +// Listen registers one keyspace per mode and serves Cache gRPC on addr. +// addr may be host:0. The bound address is Server.Addr. +func Listen(addr string, opt Options) (*Server, error) { + if opt.MTLS { + opt.TLS = true + } + eng := engine.New() + if err := register(eng); err != nil { + eng.Close() + return nil, err + } + var material *TLSMaterial + var srvOpts []grpc.ServerOption + if opt.TLS { + files, err := writeTLS() + if err != nil { + eng.Close() + return nil, err + } + material = files + cfg, err := tlsconfig.ServerFiles(files.Cert, files.Key, files.CA, opt.MTLS) + if err != nil { + eng.Close() + return nil, err + } + srvOpts = append(srvOpts, grpc.Creds(credentials.NewTLS(cfg))) + } + gs, lis, err := cacheserver.ListenAndServe(addr, eng, srvOpts...) + if err != nil { + eng.Close() + return nil, err + } + return &Server{Engine: eng, Addr: lis.Addr().String(), TLS: material, gs: gs}, nil +} + +// Close stops gRPC and the engine. It is safe to call more than once. +func (s *Server) Close() { + if s == nil { + return + } + s.once.Do(func() { + if s.gs != nil { + s.gs.Stop() + } + if s.Engine != nil { + s.Engine.Close() + } + }) +} + +// ReadyLines is the stdout block the process prints, addr first. +func ReadyLines(addr string, files *TLSMaterial) string { + out := fmt.Sprintf("addr=%s\n", addr) + if files == nil { + return out + } + out += fmt.Sprintf("ca=%s\ncert=%s\nkey=%s\nclient_cert=%s\nclient_key=%s\n", + files.CA, files.Cert, files.Key, files.ClientCert, files.ClientKey) + return out +} + +func register(eng *engine.Engine) error { + const mb int64 = 32 << 20 + ttl := time.Minute + cfgs := []keyspace.Config{ + {Name: "cacheonly", Mode: keyspace.ModeCacheOnly, MaxBytes: mb, TTL: ttl}, + {Name: "loadthrough", Mode: keyspace.ModeLoadThrough, MaxBytes: mb, TTL: ttl, + DataSource: datasource.Map{"seeded": []byte("from-source")}}, + {Name: "bloom", Mode: keyspace.ModeBloom, MaxBytes: mb, TTL: ttl, BloomBits: 1 << 16, BloomHashes: 3}, + {Name: "set", Mode: keyspace.ModeSet, MaxBytes: mb, TTL: ttl}, + {Name: "zset", Mode: keyspace.ModeZSet, MaxBytes: mb, TTL: ttl}, + {Name: "geo", Mode: keyspace.ModeGeo, MaxBytes: mb, TTL: ttl}, + {Name: "list", Mode: keyspace.ModeList, MaxBytes: mb, TTL: ttl}, + {Name: "hash", Mode: keyspace.ModeHash, MaxBytes: mb, TTL: ttl}, + {Name: "counter", Mode: keyspace.ModeCounter, MaxBytes: mb, TTL: ttl}, + {Name: "json", Mode: keyspace.ModeJSON, MaxBytes: mb, TTL: ttl}, + {Name: "bitmap", Mode: keyspace.ModeBitmap, MaxBytes: mb, TTL: ttl}, + {Name: "hll", Mode: keyspace.ModeHLL, MaxBytes: mb, TTL: ttl}, + {Name: "topk", Mode: keyspace.ModeTopK, MaxBytes: mb, TTL: ttl, TopKSize: 10}, + {Name: "cms", Mode: keyspace.ModeCMS, MaxBytes: mb, TTL: ttl}, + {Name: "vectorset", Mode: keyspace.ModeVectorSet, MaxBytes: mb, TTL: ttl, VectorDim: 4}, + {Name: "stream", Mode: keyspace.ModeStream, MaxBytes: mb, TTL: ttl}, + } + for _, cfg := range cfgs { + if err := eng.UpdateKeySpace(cfg); err != nil { + return fmt.Errorf("keyspace %s: %w", cfg.Name, err) + } + } + return nil +} diff --git a/clients/conformance/fixture_test.go b/clients/conformance/fixture_test.go new file mode 100644 index 0000000..8725433 --- /dev/null +++ b/clients/conformance/fixture_test.go @@ -0,0 +1,104 @@ +package main + +import ( + "context" + "crypto/x509" + "encoding/pem" + "errors" + "os" + "testing" + "time" + + "github.com/Code0987/supercache/pkg/client" + "github.com/Code0987/supercache/pkg/engine" +) + +func TestListenKeyspacesAndLoadThrough(t *testing.T) { + srv, err := Listen("127.0.0.1:0", Options{}) + if err != nil { + t.Fatal(err) + } + defer srv.Close() + if srv.TLS != nil { + t.Fatal("plaintext server wrote TLS files") + } + + got := map[string]string{} + for _, ks := range srv.Engine.KeySpaceSnapshots() { + got[ks.Name] = ks.Mode + } + want := map[string]string{ + "cacheonly": "CacheOnly", "loadthrough": "LoadThrough", "bloom": "Bloom", + "set": "Set", "zset": "ZSet", "geo": "Geo", "list": "List", "hash": "Hash", + "counter": "Counter", "json": "JSON", "bitmap": "Bitmap", "hll": "HLL", + "topk": "TopK", "cms": "CMS", "vectorset": "VectorSet", "stream": "Stream", + } + if len(got) != len(want) { + t.Fatalf("keyspaces: got %d want %d (%v)", len(got), len(want), got) + } + for name, mode := range want { + if got[name] != mode { + t.Fatalf("keyspace %s: mode %q want %q", name, got[name], mode) + } + } + + ctx := context.Background() + v, err := srv.Engine.Get(ctx, "loadthrough", "seeded") + if err != nil || string(v) != "from-source" { + t.Fatalf("loadthrough seeded: %v %q", err, v) + } + if _, err := srv.Engine.Get(ctx, "loadthrough", "missing"); !errors.Is(err, engine.ErrNotFound) { + t.Fatalf("missing loadthrough key: %v", err) + } + + cli, err := client.Dial(ctx, srv.Addr) + if err != nil { + t.Fatal(err) + } + defer cli.Close() + if err := cli.Put(ctx, "cacheonly", "k", []byte("v"), client.WithTTL(time.Second)); err != nil { + t.Fatal(err) + } + gotV, err := cli.Get(ctx, "cacheonly", "k") + if err != nil || string(gotV) != "v" { + t.Fatalf("grpc get: %v %q", err, gotV) + } +} + +func TestListenTLSFiles(t *testing.T) { + srv, err := Listen("127.0.0.1:0", Options{MTLS: true}) + if err != nil { + t.Fatal(err) + } + defer srv.Close() + if srv.TLS == nil { + t.Fatal("missing TLS material") + } + for _, path := range []string{srv.TLS.CA, srv.TLS.Cert, srv.TLS.Key, srv.TLS.ClientCert, srv.TLS.ClientKey} { + st, err := os.Stat(path) + if err != nil || st.Size() == 0 { + t.Fatalf("pem %s: %v", path, err) + } + } + raw, err := os.ReadFile(srv.TLS.Cert) + if err != nil { + t.Fatal(err) + } + block, _ := pem.Decode(raw) + if block == nil || block.Type != "CERTIFICATE" { + t.Fatalf("server pem: %#v", block) + } + if _, err := x509.ParseCertificate(block.Bytes); err != nil { + t.Fatal(err) + } + lines := ReadyLines(srv.Addr, srv.TLS) + if len(lines) < len("addr=") || lines[:5] != "addr=" { + t.Fatalf("ready lines: %q", lines) + } +} + +func TestReadyLinesPlaintext(t *testing.T) { + if got := ReadyLines("127.0.0.1:9", nil); got != "addr=127.0.0.1:9\n" { + t.Fatalf("got %q", got) + } +} diff --git a/clients/conformance/main.go b/clients/conformance/main.go new file mode 100644 index 0000000..7658dcc --- /dev/null +++ b/clients/conformance/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "flag" + "fmt" + "log" + "os" + "os/signal" + "syscall" +) + +func main() { + addr := flag.String("addr", "127.0.0.1:0", "cache listen address (host:0 binds a free port)") + useTLS := flag.Bool("tls", false, "serve TLS and print PEM paths") + mtls := flag.Bool("mtls", false, "require client certificates (implies -tls)") + flag.Parse() + log.SetOutput(os.Stderr) + + srv, err := Listen(*addr, Options{TLS: *useTLS, MTLS: *mtls}) + if err != nil { + log.Fatal(err) + } + defer srv.Close() + + // Write is enough. Sync fails on a pipe (the language tests capture stdout) + // with EINVAL, and the bytes are already in the pipe buffer. + if _, err := fmt.Fprint(os.Stdout, ReadyLines(srv.Addr, srv.TLS)); err != nil { + log.Fatal(err) + } + + sig := make(chan os.Signal, 1) + signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM) + <-sig +} diff --git a/clients/conformance/tls.go b/clients/conformance/tls.go new file mode 100644 index 0000000..98bac7b --- /dev/null +++ b/clients/conformance/tls.go @@ -0,0 +1,134 @@ +package main + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "math/big" + "net" + "os" + "path/filepath" + "time" +) + +func writeTLS() (*TLSMaterial, error) { + dir, err := os.MkdirTemp("", "supercache-conformance-") + if err != nil { + return nil, err + } + caCert, caKey, err := newCA() + if err != nil { + return nil, err + } + srvCert, srvKey, err := newLeaf(caCert, caKey, "localhost", []string{"localhost"}, []net.IP{net.ParseIP("127.0.0.1")}) + if err != nil { + return nil, err + } + cliCert, cliKey, err := newLeaf(caCert, caKey, "client", nil, nil) + if err != nil { + return nil, err + } + caPath, err := writePEM(filepath.Join(dir, "ca.pem"), "CERTIFICATE", caCert.Raw) + if err != nil { + return nil, err + } + certPath, err := writePEM(filepath.Join(dir, "server.pem"), "CERTIFICATE", srvCert.Raw) + if err != nil { + return nil, err + } + keyPath, err := writeKey(filepath.Join(dir, "server-key.pem"), srvKey) + if err != nil { + return nil, err + } + clientCert, err := writePEM(filepath.Join(dir, "client.pem"), "CERTIFICATE", cliCert.Raw) + if err != nil { + return nil, err + } + clientKey, err := writeKey(filepath.Join(dir, "client-key.pem"), cliKey) + if err != nil { + return nil, err + } + return &TLSMaterial{ + Dir: dir, CA: caPath, Cert: certPath, Key: keyPath, + ClientCert: clientCert, ClientKey: clientKey, + }, nil +} + +func newCA() (*x509.Certificate, *ecdsa.PrivateKey, error) { + key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, nil, err + } + tmpl := &x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{CommonName: "supercache-conformance-ca"}, + NotBefore: time.Now().Add(-time.Hour), + NotAfter: time.Now().Add(24 * time.Hour), + IsCA: true, + KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign, + BasicConstraintsValid: true, + } + der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &key.PublicKey, key) + if err != nil { + return nil, nil, err + } + cert, err := x509.ParseCertificate(der) + if err != nil { + return nil, nil, err + } + return cert, key, nil +} + +func newLeaf(ca *x509.Certificate, caKey *ecdsa.PrivateKey, cn string, dns []string, ips []net.IP) (*x509.Certificate, *ecdsa.PrivateKey, error) { + key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, nil, err + } + serial, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128)) + if err != nil { + return nil, nil, err + } + tmpl := &x509.Certificate{ + SerialNumber: serial, + Subject: pkix.Name{CommonName: cn}, + NotBefore: time.Now().Add(-time.Hour), + NotAfter: time.Now().Add(24 * time.Hour), + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, + DNSNames: dns, + IPAddresses: ips, + } + der, err := x509.CreateCertificate(rand.Reader, tmpl, ca, &key.PublicKey, caKey) + if err != nil { + return nil, nil, err + } + cert, err := x509.ParseCertificate(der) + if err != nil { + return nil, nil, err + } + return cert, key, nil +} + +func writePEM(path, typ string, der []byte) (string, error) { + f, err := os.Create(path) + if err != nil { + return "", err + } + defer f.Close() + if err := pem.Encode(f, &pem.Block{Type: typ, Bytes: der}); err != nil { + return "", err + } + return path, nil +} + +func writeKey(path string, key *ecdsa.PrivateKey) (string, error) { + b, err := x509.MarshalECPrivateKey(key) + if err != nil { + return "", fmt.Errorf("marshal key: %w", err) + } + return writePEM(path, "EC PRIVATE KEY", b) +} diff --git a/clients/node/README.md b/clients/node/README.md new file mode 100644 index 0000000..6a9c160 --- /dev/null +++ b/clients/node/README.md @@ -0,0 +1,69 @@ +# @code0987/supercache + +Async client for the SuperCache **cache** gRPC port. Node.js 22+. The package is `"private": true` and is not published to npm. + +Do not dial the peer port. + +```bash +cd clients/node +npm ci +npm run build +``` + +```js +import { dial } from "@code0987/supercache"; + +const c = dial("127.0.0.1:9000"); +await c.put("cacheonly", "greeting", "hello"); // string values are UTF-8 +await c.put("cacheonly", "forever", "x", { ttlMs: 0 }); // ttlSet, no expiry +console.log(Buffer.from(await c.get("cacheonly", "greeting")).toString()); +c.close(); +``` + +Point `NODE_PATH` or a workspace at `clients/node` after `npm run build`. The built entry is `dist/src/index.js`. + +TLS: + +```js +import { dialTls } from "@code0987/supercache"; + +const c = dialTls("127.0.0.1:9000", { + caFile: "ca.pem", + serverName: "cache.example", + clientCert: "client.pem", // optional; set key too + clientKey: "client-key.pem", +}); +``` + +`serverName` is required. Pass both client files or neither. + +## Errors + +| Error | When | +|-------|------| +| `NotFound` | `get` returned `found=false` | +| `StatusError` | gRPC status. `.code` is `NOT_FOUND`, `INVALID_ARGUMENT`, `UNAVAILABLE`, … | +| `KeyErrors` | `putMany` / `deleteMany` body listed per-key failures | +| `PeerFailures` | `delete` body listed replica failures | + +A missing keyspace is `StatusError` code `NOT_FOUND`, not `NotFound`. + +## Session + +`Session` keeps a sticky seed list. It walks the list on dial. After `UNAVAILABLE` or a connection reset/refused/broken pipe it drops the channel, advances one seed, and retries that call once. It does not retry `NotFound`, `INVALID_ARGUMENT`, batch errors, or a call deadline. + +```js +import { Session } from "@code0987/supercache"; + +const s = new Session(["127.0.0.1:9000", "127.0.0.1:9010"], { timeoutMs: 5000 }); +await s.put("cacheonly", "k", "v"); +s.close(); +``` + +There is no default per-call deadline. Pass `timeoutMs` on the session or as the last argument of a call. `put` / `putMany` take `{ ttlMs, timeoutMs }` instead. `sc` uses 5s; this library does not. + +## Methods + +Names follow `pkg/client` in camelCase (`putMany`, `zRangeByScore`, `topKList`, `xRevRange`, `lLen`). The full map is `SURFACE` in `scripts/check-client-surface.py`. Returned bytes are `Uint8Array`. A vector is an array of numbers, not a string. + +`bloomTest` / `setContains` / `hExists` return false when the entry is absent. `hGet`, `lPop`, `rPop`, `lIndex`, `jsonGet`, and `vEmb` return `null`. `bitGet` returns `{ value, found }`. Counts that can be absent (`counterGet`, `hllCount`, `cmsQuery`, `vCard`, `vDim`, `xLen`) return `{ value, found }`. `topKList` returns `{ entries, found }`. diff --git a/clients/node/examples/kv.ts b/clients/node/examples/kv.ts new file mode 100644 index 0000000..ec4581b --- /dev/null +++ b/clients/node/examples/kv.ts @@ -0,0 +1,16 @@ +/** + * Minimal CacheOnly put/get. + * Build the package first (`npm run build`) and run with Node 22+ + * from clients/node: `node --experimental-strip-types examples/kv.ts` + * after the demo keyspace node is listening on 127.0.0.1:9000. + */ +import { dial } from "../dist/src/index.js"; + +const client = dial("127.0.0.1:9000"); +try { + await client.put("cacheonly", "greeting", "hello"); + const value = await client.get("cacheonly", "greeting"); + console.log(Buffer.from(value).toString("utf8")); +} finally { + client.close(); +} diff --git a/clients/node/package-lock.json b/clients/node/package-lock.json new file mode 100644 index 0000000..4ff38e5 --- /dev/null +++ b/clients/node/package-lock.json @@ -0,0 +1,441 @@ +{ + "name": "@code0987/supercache", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@code0987/supercache", + "version": "0.1.0", + "dependencies": { + "@bufbuild/protobuf": "^2.16.0", + "@grpc/grpc-js": "1.12.6" + }, + "devDependencies": { + "@types/node": "22.13.10", + "ts-proto": "2.7.7", + "typescript": "5.8.2" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@bufbuild/protobuf": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.16.0.tgz", + "integrity": "sha512-FWa0sPlqYGJgpTs6OxBRcL/AW4JT0OIO+W1ajerluoTVh8CV0B7XM1qsNCRgnkSCkRCgOICKHRQlY17jrsm0+Q==", + "license": "(Apache-2.0 AND BSD-3-Clause)" + }, + "node_modules/@grpc/grpc-js": { + "version": "1.12.6", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.6.tgz", + "integrity": "sha512-JXUj6PI0oqqzTGvKtzOkxtpsyPRNsrmhh41TtIz/zEB6J+AUiZZ0dxWzcMwO9Ns5rmSPuMdghlTbUuqIM48d3Q==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", + "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", + "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", + "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", + "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", + "license": "BSD-3-Clause" + }, + "node_modules/@types/node": { + "version": "22.13.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", + "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/case-anything": { + "version": "2.1.13", + "resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.13.tgz", + "integrity": "sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dprint-node": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/dprint-node/-/dprint-node-1.0.8.tgz", + "integrity": "sha512-iVKnUtYfGrYcW1ZAlfR/F59cUVL8QIhWoBJoSjkkdua/dkWIgjZfiLMeTjiB06X0ZLkQ0M2C1VbUj/CxkIf1zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^1.0.3" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/protobufjs": { + "version": "7.6.6", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.6.tgz", + "integrity": "sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.1", + "@protobufjs/fetch": "^1.1.1", + "@protobufjs/float": "^1.0.2", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.1", + "@types/node": ">=13.7.0", + "long": "^5.3.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-poet": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ts-poet/-/ts-poet-6.12.0.tgz", + "integrity": "sha512-xo+iRNMWqyvXpFTaOAvLPA5QAWO6TZrSUs5s4Odaya3epqofBu/fMLHEWl8jPmjhA0s9sgj9sNvF1BmaQlmQkA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "dprint-node": "^1.0.8" + } + }, + "node_modules/ts-proto": { + "version": "2.7.7", + "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-2.7.7.tgz", + "integrity": "sha512-/OfN9/Yriji2bbpOysZ/Jzc96isOKz+eBTJEcKaIZ0PR6x1TNgVm4Lz0zfbo+J0jwFO7fJjJyssefBPQ0o1V9A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@bufbuild/protobuf": "^2.0.0", + "case-anything": "^2.1.13", + "ts-poet": "^6.12.0", + "ts-proto-descriptors": "2.0.0" + }, + "bin": { + "protoc-gen-ts_proto": "protoc-gen-ts_proto" + } + }, + "node_modules/ts-proto-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-proto-descriptors/-/ts-proto-descriptors-2.0.0.tgz", + "integrity": "sha512-wHcTH3xIv11jxgkX5OyCSFfw27agpInAd6yh89hKG6zqIXnjW9SYqSER2CVQxdPj4czeOhGagNvZBEbJPy7qkw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@bufbuild/protobuf": "^2.0.0" + } + }, + "node_modules/typescript": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/clients/node/package.json b/clients/node/package.json new file mode 100644 index 0000000..8e9ceca --- /dev/null +++ b/clients/node/package.json @@ -0,0 +1,31 @@ +{ + "name": "@code0987/supercache", + "version": "0.1.0", + "private": true, + "description": "SuperCache Cache gRPC client for Node.js", + "type": "module", + "engines": { + "node": ">=22" + }, + "main": "./dist/src/index.js", + "types": "./dist/src/index.d.ts", + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "import": "./dist/src/index.js" + } + }, + "scripts": { + "build": "tsc", + "test": "tsc && node --test dist/test/client.test.js" + }, + "dependencies": { + "@bufbuild/protobuf": "^2.16.0", + "@grpc/grpc-js": "1.12.6" + }, + "devDependencies": { + "@types/node": "22.13.10", + "ts-proto": "2.7.7", + "typescript": "5.8.2" + } +} diff --git a/clients/node/src/client.ts b/clients/node/src/client.ts new file mode 100644 index 0000000..b52ecae --- /dev/null +++ b/clients/node/src/client.ts @@ -0,0 +1,670 @@ +/** + * Async Cache client. Semantics match pkg/client in the Go module. + * Dial the cache port, not the peer port. + * + * Return types live in ./types.js. This file is the call path only. + */ + +import { readFileSync } from "node:fs"; + +import { + type ChannelCredentials, + Client as GrpcClient, + credentials, + Metadata, + status, + type ServiceError, +} from "@grpc/grpc-js"; + +import * as pb from "./gen/cache.js"; +import { KeyErrors, NotFound, PeerFailures, StatusError, type KeyErrorItem, type PeerFailure } from "./errors.js"; +import type { + BitPos, + BitValue, + Bytes, + GeoMember, + HashField, + Present, + PutOptions, + StreamEntry, + TlsOptions, + TopKResult, + VSimHit, + ZMember, +} from "./types.js"; + +function toBytes(value: Bytes, what: string): Buffer { + if (typeof value === "string") return Buffer.from(value, "utf8"); + if (Buffer.isBuffer(value)) return value; + if (value instanceof Uint8Array) return Buffer.from(value); + throw new TypeError(`${what} must be a string or Uint8Array`); +} + +function bytesOut(value: Uint8Array | undefined): Uint8Array { + return value ? Uint8Array.from(value) : new Uint8Array(); +} + +function vec(value: readonly number[]): number[] { + if (typeof value === "string" || value instanceof Uint8Array) { + throw new TypeError("vector must be a sequence of numbers"); + } + return Array.from(value, (n) => { + if (typeof n !== "number" || !Number.isFinite(n)) throw new TypeError("vector must be finite numbers"); + return n; + }); +} + +function ttlFields(ttlMs: number | undefined): { ttlNanos: number; ttlSet: boolean } { + if (ttlMs === undefined) return { ttlNanos: 0, ttlSet: false }; + if (!Number.isFinite(ttlMs) || ttlMs < 0) throw new TypeError("ttlMs must be >= 0"); + return { ttlNanos: Math.round(ttlMs * 1_000_000), ttlSet: true }; +} + +function statusFrom(err: ServiceError): StatusError { + const name = status[err.code]; + const code = typeof name === "string" ? name : String(err.code); + return new StatusError(code, err.details || err.message); +} + +function keyErrors(errors: { key: string; message: string; peerFailures?: { peerId: string; message: string }[] }[]): void { + if (!errors || errors.length === 0) return; + const items: KeyErrorItem[] = errors.map((e) => ({ + key: e.key, + message: e.message, + peerFailures: (e.peerFailures ?? []).map((p) => ({ peerId: p.peerId, message: p.message })), + })); + throw new KeyErrors(items); +} + +function peerFailures(failures: { peerId: string; message: string }[] | undefined): void { + if (!failures || failures.length === 0) return; + const items: PeerFailure[] = failures.map((p) => ({ peerId: p.peerId, message: p.message })); + throw new PeerFailures(items); +} + +export class Client { + private closed = false; + + constructor( + readonly raw: InstanceType, + readonly timeoutMs?: number, + ) {} + + close(): void { + if (this.closed) return; + this.closed = true; + this.raw.close(); + } + + ready(timeoutMs: number): Promise { + return new Promise((resolve, reject) => { + (this.raw as GrpcClient).waitForReady(new Date(Date.now() + timeoutMs), (err) => { + if (err) reject(err); + else resolve(); + }); + }); + } + + private rpc(method: string, request: object, timeoutMs?: number): Promise { + const ms = timeoutMs ?? this.timeoutMs; + return new Promise((resolve, reject) => { + const cb = (err: ServiceError | null, res: T) => { + if (err) reject(statusFrom(err)); + else resolve(res); + }; + const fn = (this.raw as unknown as Record void>)[method]; + if (ms == null) { + fn.call(this.raw, request, cb); + return; + } + fn.call(this.raw, request, new Metadata(), { deadline: new Date(Date.now() + ms) }, cb); + }); + } + + get(keyspace: string, key: string, timeoutMs?: number): Promise { + return this.rpc("get", pb.GetRequest.fromPartial({ keyspace, key }), timeoutMs).then((resp) => { + if (!resp.found) throw new NotFound(`${keyspace}/${key}`); + return bytesOut(resp.value); + }); + } + + put(keyspace: string, key: string, value: Bytes, opts?: PutOptions): Promise { + const ttl = ttlFields(opts?.ttlMs); + return this.rpc( + "put", + pb.PutRequest.fromPartial({ keyspace, key, value: toBytes(value, "value"), ttlNanos: ttl.ttlNanos, ttlSet: ttl.ttlSet }), + opts?.timeoutMs, + ).then(() => undefined); + } + + putMany(keyspace: string, items: ReadonlyArray<{ key: string; value: Bytes }>, opts?: PutOptions): Promise { + const ttl = ttlFields(opts?.ttlMs); + return this.rpc( + "putMany", + pb.PutManyRequest.fromPartial({ + keyspace, + items: items.map((it) => ({ key: it.key, value: toBytes(it.value, "value") })), + ttlNanos: ttl.ttlNanos, + ttlSet: ttl.ttlSet, + }), + opts?.timeoutMs, + ).then((resp) => keyErrors(resp.errors)); + } + + delete(keyspace: string, key: string, timeoutMs?: number): Promise { + return this.rpc("delete", pb.DeleteRequest.fromPartial({ keyspace, key }), timeoutMs).then((resp) => { + peerFailures(resp.peerFailures); + }); + } + + deleteMany(keyspace: string, keys: readonly string[], timeoutMs?: number): Promise { + return this.rpc( + "deleteMany", + pb.DeleteManyRequest.fromPartial({ keyspace, keys: [...keys] }), + timeoutMs, + ).then((resp) => keyErrors(resp.errors)); + } + + bloomAdd(keyspace: string, name: string, item: Bytes, timeoutMs?: number): Promise { + return this.rpc("bloomAdd", pb.BloomAddRequest.fromPartial({ keyspace, name, item: toBytes(item, "item") }), timeoutMs).then( + () => undefined, + ); + } + + bloomTest(keyspace: string, name: string, item: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "bloomTest", + pb.BloomTestRequest.fromPartial({ keyspace, name, item: toBytes(item, "item") }), + timeoutMs, + ).then((resp) => resp.maybe); + } + + setAdd(keyspace: string, name: string, item: Bytes, timeoutMs?: number): Promise { + return this.rpc("setAdd", pb.SetAddRequest.fromPartial({ keyspace, name, item: toBytes(item, "item") }), timeoutMs).then( + () => undefined, + ); + } + + setRemove(keyspace: string, name: string, item: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "setRemove", + pb.SetRemoveRequest.fromPartial({ keyspace, name, item: toBytes(item, "item") }), + timeoutMs, + ).then(() => undefined); + } + + setContains(keyspace: string, name: string, item: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "setContains", + pb.SetContainsRequest.fromPartial({ keyspace, name, item: toBytes(item, "item") }), + timeoutMs, + ).then((resp) => resp.present); + } + + setCard(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("setCard", pb.SetCardRequest.fromPartial({ keyspace, name }), timeoutMs).then( + (resp) => resp.card, + ); + } + + setMembers(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("setMembers", pb.SetMembersRequest.fromPartial({ keyspace, name }), timeoutMs).then( + (resp) => resp.members.map((m) => bytesOut(m)), + ); + } + + zAdd(keyspace: string, name: string, member: Bytes, score: number, timeoutMs?: number): Promise { + return this.rpc( + "zAdd", + pb.ZAddRequest.fromPartial({ keyspace, name, member: toBytes(member, "member"), score }), + timeoutMs, + ).then(() => undefined); + } + + zRem(keyspace: string, name: string, member: Bytes, timeoutMs?: number): Promise { + return this.rpc("zRem", pb.ZRemRequest.fromPartial({ keyspace, name, member: toBytes(member, "member") }), timeoutMs).then( + () => undefined, + ); + } + + zScore(keyspace: string, name: string, member: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "zScore", + pb.ZScoreRequest.fromPartial({ keyspace, name, member: toBytes(member, "member") }), + timeoutMs, + ).then((resp) => (resp.present ? resp.score : null)); + } + + zCard(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("zCard", pb.ZCardRequest.fromPartial({ keyspace, name }), timeoutMs).then((resp) => resp.card); + } + + zRange(keyspace: string, name: string, start: number, stop: number, timeoutMs?: number): Promise { + return this.rpc( + "zRange", + pb.ZRangeRequest.fromPartial({ keyspace, name, start, stop }), + timeoutMs, + ).then((resp) => resp.members.map((m) => ({ member: bytesOut(m.member), score: m.score }))); + } + + zRangeByScore(keyspace: string, name: string, min: number, max: number, timeoutMs?: number): Promise { + return this.rpc( + "zRangeByScore", + pb.ZRangeByScoreRequest.fromPartial({ keyspace, name, min, max }), + timeoutMs, + ).then((resp) => resp.members.map((m) => ({ member: bytesOut(m.member), score: m.score }))); + } + + geoAdd(keyspace: string, name: string, member: Bytes, lon: number, lat: number, timeoutMs?: number): Promise { + return this.rpc( + "geoAdd", + pb.GeoAddRequest.fromPartial({ keyspace, name, member: toBytes(member, "member"), lon, lat }), + timeoutMs, + ).then(() => undefined); + } + + geoRem(keyspace: string, name: string, member: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "geoRem", + pb.GeoRemRequest.fromPartial({ keyspace, name, member: toBytes(member, "member") }), + timeoutMs, + ).then(() => undefined); + } + + geoPos(keyspace: string, name: string, member: Bytes, timeoutMs?: number): Promise<[number, number] | null> { + return this.rpc( + "geoPos", + pb.GeoPosRequest.fromPartial({ keyspace, name, member: toBytes(member, "member") }), + timeoutMs, + ).then((resp) => (resp.present ? [resp.lon, resp.lat] : null)); + } + + geoCard(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("geoCard", pb.GeoCardRequest.fromPartial({ keyspace, name }), timeoutMs).then( + (resp) => resp.card, + ); + } + + geoDist(keyspace: string, name: string, a: Bytes, b: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "geoDist", + pb.GeoDistRequest.fromPartial({ keyspace, name, a: toBytes(a, "a"), b: toBytes(b, "b") }), + timeoutMs, + ).then((resp) => (resp.present ? resp.meters : null)); + } + + geoRadius( + keyspace: string, + name: string, + lon: number, + lat: number, + radiusM: number, + limit: number, + timeoutMs?: number, + ): Promise { + return this.rpc( + "geoRadius", + pb.GeoRadiusRequest.fromPartial({ keyspace, name, lon, lat, radiusMeters: radiusM, limit }), + timeoutMs, + ).then((resp) => + resp.members.map((m) => ({ member: bytesOut(m.member), lon: m.lon, lat: m.lat, dist: m.distMeters })), + ); + } + + lPush(keyspace: string, name: string, item: Bytes, timeoutMs?: number): Promise { + return this.rpc("lPush", pb.LPushRequest.fromPartial({ keyspace, name, item: toBytes(item, "item") }), timeoutMs).then( + () => undefined, + ); + } + + rPush(keyspace: string, name: string, item: Bytes, timeoutMs?: number): Promise { + return this.rpc("rPush", pb.RPushRequest.fromPartial({ keyspace, name, item: toBytes(item, "item") }), timeoutMs).then( + () => undefined, + ); + } + + lPop(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("lPop", pb.LPopRequest.fromPartial({ keyspace, name }), timeoutMs).then((resp) => + resp.present ? bytesOut(resp.item) : null, + ); + } + + rPop(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("rPop", pb.RPopRequest.fromPartial({ keyspace, name }), timeoutMs).then((resp) => + resp.present ? bytesOut(resp.item) : null, + ); + } + + lLen(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("lLen", pb.LLenRequest.fromPartial({ keyspace, name }), timeoutMs).then((resp) => resp.len); + } + + lIndex(keyspace: string, name: string, index: number, timeoutMs?: number): Promise { + return this.rpc("lIndex", pb.LIndexRequest.fromPartial({ keyspace, name, index }), timeoutMs).then( + (resp) => (resp.present ? bytesOut(resp.item) : null), + ); + } + + lRange(keyspace: string, name: string, start: number, stop: number, timeoutMs?: number): Promise { + return this.rpc("lRange", pb.LRangeRequest.fromPartial({ keyspace, name, start, stop }), timeoutMs).then( + (resp) => resp.items.map((item) => bytesOut(item)), + ); + } + + hSet(keyspace: string, name: string, field: Bytes, value: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "hSet", + pb.HSetRequest.fromPartial({ keyspace, name, field: toBytes(field, "field"), value: toBytes(value, "value") }), + timeoutMs, + ).then(() => undefined); + } + + hGet(keyspace: string, name: string, field: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "hGet", + pb.HGetRequest.fromPartial({ keyspace, name, field: toBytes(field, "field") }), + timeoutMs, + ).then((resp) => (resp.present ? bytesOut(resp.value) : null)); + } + + hDel(keyspace: string, name: string, field: Bytes, timeoutMs?: number): Promise { + return this.rpc("hDel", pb.HDelRequest.fromPartial({ keyspace, name, field: toBytes(field, "field") }), timeoutMs).then( + () => undefined, + ); + } + + hExists(keyspace: string, name: string, field: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "hExists", + pb.HExistsRequest.fromPartial({ keyspace, name, field: toBytes(field, "field") }), + timeoutMs, + ).then((resp) => resp.present); + } + + hLen(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("hLen", pb.HLenRequest.fromPartial({ keyspace, name }), timeoutMs).then((resp) => resp.len); + } + + hGetAll(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("hGetAll", pb.HGetAllRequest.fromPartial({ keyspace, name }), timeoutMs).then((resp) => + resp.fields.map((f) => ({ field: bytesOut(f.field), value: bytesOut(f.value) })), + ); + } + + incr(keyspace: string, name: string, delta: number, timeoutMs?: number): Promise { + return this.rpc("incr", pb.IncrRequest.fromPartial({ keyspace, name, delta }), timeoutMs).then( + (resp) => resp.value, + ); + } + + counterGet(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("counterGet", pb.CounterGetRequest.fromPartial({ keyspace, name }), timeoutMs).then( + (resp) => ({ value: resp.value, found: resp.present }), + ); + } + + jsonSet(keyspace: string, name: string, path: string, value: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "jsonSet", + pb.JsonSetRequest.fromPartial({ keyspace, name, path, value: toBytes(value, "value") }), + timeoutMs, + ).then(() => undefined); + } + + jsonGet(keyspace: string, name: string, path: string, timeoutMs?: number): Promise { + return this.rpc("jsonGet", pb.JsonGetRequest.fromPartial({ keyspace, name, path }), timeoutMs).then( + (resp) => (resp.present ? bytesOut(resp.value) : null), + ); + } + + jsonDel(keyspace: string, name: string, path: string, timeoutMs?: number): Promise { + return this.rpc("jsonDel", pb.JsonDelRequest.fromPartial({ keyspace, name, path }), timeoutMs).then(() => undefined); + } + + bitSet(keyspace: string, name: string, offset: number, bit: boolean, timeoutMs?: number): Promise { + return this.rpc("bitSet", pb.BitSetRequest.fromPartial({ keyspace, name, offset, bit }), timeoutMs).then(() => undefined); + } + + bitGet(keyspace: string, name: string, offset: number, timeoutMs?: number): Promise { + return this.rpc("bitGet", pb.BitGetRequest.fromPartial({ keyspace, name, offset }), timeoutMs).then( + (resp) => ({ value: resp.bit, found: resp.present }), + ); + } + + bitCount(keyspace: string, name: string, start: number, end: number, timeoutMs?: number): Promise { + return this.rpc( + "bitCount", + pb.BitCountRequest.fromPartial({ keyspace, name, start, end }), + timeoutMs, + ).then((resp) => resp.count); + } + + bitPos(keyspace: string, name: string, bit: boolean, start: number, end: number, timeoutMs?: number): Promise { + return this.rpc( + "bitPos", + pb.BitPosRequest.fromPartial({ keyspace, name, bit, start, end }), + timeoutMs, + ).then((resp) => ({ pos: resp.pos, found: resp.found })); + } + + hllAdd(keyspace: string, name: string, item: Bytes, timeoutMs?: number): Promise { + return this.rpc("hllAdd", pb.HLLAddRequest.fromPartial({ keyspace, name, item: toBytes(item, "item") }), timeoutMs).then( + () => undefined, + ); + } + + hllCount(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("hllCount", pb.HLLCountRequest.fromPartial({ keyspace, name }), timeoutMs).then( + (resp) => ({ value: resp.count, found: resp.present }), + ); + } + + topKAdd(keyspace: string, name: string, item: Bytes, timeoutMs?: number): Promise { + return this.rpc("topKAdd", pb.TopKAddRequest.fromPartial({ keyspace, name, item: toBytes(item, "item") }), timeoutMs).then( + () => undefined, + ); + } + + topKList(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("topKList", pb.TopKListRequest.fromPartial({ keyspace, name }), timeoutMs).then( + (resp) => ({ + found: resp.present, + entries: resp.entries.map((e) => ({ item: bytesOut(e.item), count: e.count })), + }), + ); + } + + cmsIncr(keyspace: string, name: string, item: Bytes, n: number, timeoutMs?: number): Promise { + return this.rpc( + "cmsIncr", + pb.CMSIncrRequest.fromPartial({ keyspace, name, item: toBytes(item, "item"), n }), + timeoutMs, + ).then(() => undefined); + } + + cmsQuery(keyspace: string, name: string, item: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "cmsQuery", + pb.CMSQueryRequest.fromPartial({ keyspace, name, item: toBytes(item, "item") }), + timeoutMs, + ).then((resp) => ({ value: resp.count, found: resp.present })); + } + + vAdd(keyspace: string, name: string, member: Bytes, vector: readonly number[], timeoutMs?: number): Promise { + return this.rpc( + "vAdd", + pb.VAddRequest.fromPartial({ keyspace, name, member: toBytes(member, "member"), vec: vec(vector) }), + timeoutMs, + ).then(() => undefined); + } + + vRem(keyspace: string, name: string, member: Bytes, timeoutMs?: number): Promise { + return this.rpc("vRem", pb.VRemRequest.fromPartial({ keyspace, name, member: toBytes(member, "member") }), timeoutMs).then( + () => undefined, + ); + } + + vSim(keyspace: string, name: string, vector: readonly number[], k: number, timeoutMs?: number): Promise { + return this.rpc( + "vSim", + pb.VSimRequest.fromPartial({ keyspace, name, vec: vec(vector), k }), + timeoutMs, + ).then((resp) => resp.hits.map((h) => ({ member: bytesOut(h.member), score: h.score }))); + } + + vCard(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("vCard", pb.VCardRequest.fromPartial({ keyspace, name }), timeoutMs).then((resp) => ({ + value: resp.n, + found: resp.present, + })); + } + + vDim(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("vDim", pb.VDimRequest.fromPartial({ keyspace, name }), timeoutMs).then((resp) => ({ + value: resp.dim, + found: resp.present, + })); + } + + vEmb(keyspace: string, name: string, member: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "vEmb", + pb.VEmbRequest.fromPartial({ keyspace, name, member: toBytes(member, "member") }), + timeoutMs, + ).then((resp) => (resp.found ? [...resp.vec] : null)); + } + + xAdd(keyspace: string, name: string, payload: Bytes, timeoutMs?: number): Promise { + return this.rpc( + "xAdd", + pb.XAddRequest.fromPartial({ keyspace, name, payload: toBytes(payload, "payload") }), + timeoutMs, + ).then((resp) => resp.id); + } + + xRange(keyspace: string, name: string, start: string, end: string, count: number, timeoutMs?: number): Promise { + return this.rpc( + "xRange", + pb.XRangeRequest.fromPartial({ keyspace, name, start, end, count }), + timeoutMs, + ).then((resp) => resp.entries.map((e) => ({ id: e.id, payload: bytesOut(e.payload) }))); + } + + xRevRange( + keyspace: string, + name: string, + start: string, + end: string, + count: number, + timeoutMs?: number, + ): Promise { + return this.rpc( + "xRevRange", + pb.XRevRangeRequest.fromPartial({ keyspace, name, start, end, count }), + timeoutMs, + ).then((resp) => resp.entries.map((e) => ({ id: e.id, payload: bytesOut(e.payload) }))); + } + + xLen(keyspace: string, name: string, timeoutMs?: number): Promise { + return this.rpc("xLen", pb.XLenRequest.fromPartial({ keyspace, name }), timeoutMs).then((resp) => ({ + value: resp.n, + found: resp.present, + })); + } + + xDel(keyspace: string, name: string, id: string, timeoutMs?: number): Promise { + return this.rpc("xDel", pb.XDelRequest.fromPartial({ keyspace, name, id }), timeoutMs).then(() => undefined); + } + + xTrim(keyspace: string, name: string, maxLen: number, timeoutMs?: number): Promise { + return this.rpc("xTrim", pb.XTrimRequest.fromPartial({ keyspace, name, maxLen }), timeoutMs).then(() => undefined); + } +} + +/** Public method names. Session forwards each of these with one transport retry. */ +export const clientMethods = [ + "get", + "put", + "putMany", + "delete", + "deleteMany", + "bloomAdd", + "bloomTest", + "setAdd", + "setRemove", + "setContains", + "setCard", + "setMembers", + "zAdd", + "zRem", + "zScore", + "zCard", + "zRange", + "zRangeByScore", + "geoAdd", + "geoRem", + "geoPos", + "geoCard", + "geoDist", + "geoRadius", + "lPush", + "rPush", + "lPop", + "rPop", + "lLen", + "lIndex", + "lRange", + "hSet", + "hGet", + "hDel", + "hExists", + "hLen", + "hGetAll", + "incr", + "counterGet", + "jsonSet", + "jsonGet", + "jsonDel", + "bitSet", + "bitGet", + "bitCount", + "bitPos", + "hllAdd", + "hllCount", + "topKAdd", + "topKList", + "cmsIncr", + "cmsQuery", + "vAdd", + "vRem", + "vSim", + "vCard", + "vDim", + "vEmb", + "xAdd", + "xRange", + "xRevRange", + "xLen", + "xDel", + "xTrim", +] as const; + +export type CacheApi = Pick; + +export function dial(addr: string, timeoutMs?: number): Client { + return new Client(new pb.CacheClient(addr, credentials.createInsecure()), timeoutMs); +} + +export function dialTls(addr: string, tls: TlsOptions, timeoutMs?: number): Client { + if (!tls.serverName) throw new TypeError("serverName is required"); + if (Boolean(tls.clientCert) !== Boolean(tls.clientKey)) { + throw new TypeError("clientCert and clientKey must both be set"); + } + const creds: ChannelCredentials = credentials.createSsl( + readFileSync(tls.caFile), + tls.clientKey ? readFileSync(tls.clientKey) : null, + tls.clientCert ? readFileSync(tls.clientCert) : null, + ); + const raw = new pb.CacheClient(addr, creds, { "grpc.ssl_target_name_override": tls.serverName }); + return new Client(raw, timeoutMs); +} diff --git a/clients/node/src/errors.ts b/clients/node/src/errors.ts new file mode 100644 index 0000000..3eb75bf --- /dev/null +++ b/clients/node/src/errors.ts @@ -0,0 +1,60 @@ +/** Get found=false. A gRPC status is StatusError, even when the code is NOT_FOUND. */ +export class NotFound extends Error { + constructor(message = "supercache: not found") { + super(message); + this.name = "NotFound"; + } +} + +/** gRPC status. code is the name, for example NOT_FOUND or UNAVAILABLE. */ +export class StatusError extends Error { + constructor( + readonly code: string, + message: string, + ) { + super(`${code}: ${message}`); + this.name = "StatusError"; + } +} + +export interface PeerFailure { + peerId: string; + message: string; +} + +export class PeerFailures extends Error { + constructor(readonly failures: PeerFailure[]) { + super(`${failures.length} peer failure(s)`); + this.name = "PeerFailures"; + } +} + +export interface KeyErrorItem { + key: string; + message: string; + peerFailures: PeerFailure[]; +} + +export class KeyErrors extends Error { + constructor(readonly errors: KeyErrorItem[]) { + super(`${errors.length} key error(s)`); + this.name = "KeyErrors"; + } +} + +const transportSnips = [ + "connection refused", + "connection reset", + "broken pipe", + "socket hang up", + "econnrefused", + "econnreset", +]; + +/** Dead connection. A call deadline is not transport: the RPC may already have landed. */ +export function isTransport(err: unknown): boolean { + if (!(err instanceof StatusError)) return false; + if (err.code === "UNAVAILABLE") return true; + const msg = err.message.toLowerCase(); + return transportSnips.some((needle) => msg.includes(needle)); +} diff --git a/clients/node/src/gen/cache.ts b/clients/node/src/gen/cache.ts new file mode 100644 index 0000000..574a69c --- /dev/null +++ b/clients/node/src/gen/cache.ts @@ -0,0 +1,12742 @@ +// Code generated by protoc-gen-ts_proto. DO NOT EDIT. +// versions: +// protoc-gen-ts_proto v2.7.7 +// protoc v5.28.3 +// source: cache.proto + +/* eslint-disable */ +import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire"; +import { + type CallOptions, + type ChannelCredentials, + Client, + type ClientOptions, + type ClientUnaryCall, + type handleUnaryCall, + makeGenericClientConstructor, + type Metadata, + type ServiceError, + type UntypedServiceImplementation, +} from "@grpc/grpc-js"; + +export const protobufPackage = "supercache.cache.v1"; + +export interface GetRequest { + keyspace: string; + key: string; +} + +export interface GetResponse { + found: boolean; + value: Buffer; +} + +export interface PutRequest { + keyspace: string; + key: string; + value: Buffer; + ttlNanos: number; + ttlSet: boolean; +} + +export interface PutResponse { +} + +export interface KV { + key: string; + value: Buffer; +} + +export interface PutManyRequest { + keyspace: string; + items: KV[]; + ttlNanos: number; + ttlSet: boolean; +} + +export interface KeyError { + key: string; + message: string; + /** Optional structured peer failures (e.g. DeleteMany wrapping MultiError). */ + peerFailures: PeerFailure[]; +} + +export interface PutManyResponse { + errors: KeyError[]; +} + +export interface DeleteRequest { + keyspace: string; + key: string; +} + +export interface PeerFailure { + peerId: string; + message: string; +} + +export interface DeleteResponse { + peerFailures: PeerFailure[]; +} + +export interface DeleteManyRequest { + keyspace: string; + keys: string[]; +} + +export interface DeleteManyResponse { + errors: KeyError[]; +} + +export interface BloomAddRequest { + keyspace: string; + name: string; + item: Buffer; +} + +export interface BloomAddResponse { +} + +export interface BloomTestRequest { + keyspace: string; + name: string; + item: Buffer; +} + +export interface BloomTestResponse { + /** false = definitely not present */ + maybe: boolean; +} + +export interface SetAddRequest { + keyspace: string; + name: string; + item: Buffer; +} + +export interface SetAddResponse { +} + +export interface SetRemoveRequest { + keyspace: string; + name: string; + item: Buffer; +} + +export interface SetRemoveResponse { +} + +export interface SetContainsRequest { + keyspace: string; + name: string; + item: Buffer; +} + +export interface SetContainsResponse { + present: boolean; +} + +export interface SetCardRequest { + keyspace: string; + name: string; +} + +export interface SetCardResponse { + card: number; +} + +export interface SetMembersRequest { + keyspace: string; + name: string; +} + +export interface SetMembersResponse { + members: Buffer[]; +} + +export interface ZMember { + member: Buffer; + score: number; +} + +export interface ZAddRequest { + keyspace: string; + name: string; + member: Buffer; + score: number; +} + +export interface ZAddResponse { +} + +export interface ZRemRequest { + keyspace: string; + name: string; + member: Buffer; +} + +export interface ZRemResponse { +} + +export interface ZScoreRequest { + keyspace: string; + name: string; + member: Buffer; +} + +export interface ZScoreResponse { + present: boolean; + score: number; +} + +export interface ZCardRequest { + keyspace: string; + name: string; +} + +export interface ZCardResponse { + card: number; +} + +export interface ZRangeRequest { + keyspace: string; + name: string; + start: number; + stop: number; +} + +export interface ZRangeByScoreRequest { + keyspace: string; + name: string; + min: number; + max: number; +} + +export interface ZRangeResponse { + members: ZMember[]; +} + +export interface GeoMember { + member: Buffer; + lon: number; + lat: number; + distMeters: number; +} + +export interface GeoAddRequest { + keyspace: string; + name: string; + member: Buffer; + lon: number; + lat: number; +} + +export interface GeoAddResponse { +} + +export interface GeoRemRequest { + keyspace: string; + name: string; + member: Buffer; +} + +export interface GeoRemResponse { +} + +export interface GeoPosRequest { + keyspace: string; + name: string; + member: Buffer; +} + +export interface GeoPosResponse { + present: boolean; + lon: number; + lat: number; +} + +export interface GeoCardRequest { + keyspace: string; + name: string; +} + +export interface GeoCardResponse { + card: number; +} + +export interface GeoDistRequest { + keyspace: string; + name: string; + a: Buffer; + b: Buffer; +} + +export interface GeoDistResponse { + present: boolean; + meters: number; +} + +export interface GeoRadiusRequest { + keyspace: string; + name: string; + lon: number; + lat: number; + radiusMeters: number; + limit: number; +} + +export interface GeoRadiusResponse { + members: GeoMember[]; +} + +export interface LPushRequest { + keyspace: string; + name: string; + item: Buffer; +} + +export interface LPushResponse { +} + +export interface RPushRequest { + keyspace: string; + name: string; + item: Buffer; +} + +export interface RPushResponse { +} + +export interface LPopRequest { + keyspace: string; + name: string; +} + +export interface LPopResponse { + present: boolean; + item: Buffer; +} + +export interface RPopRequest { + keyspace: string; + name: string; +} + +export interface RPopResponse { + present: boolean; + item: Buffer; +} + +export interface LLenRequest { + keyspace: string; + name: string; +} + +export interface LLenResponse { + len: number; +} + +export interface LIndexRequest { + keyspace: string; + name: string; + index: number; +} + +export interface LIndexResponse { + present: boolean; + item: Buffer; +} + +export interface LRangeRequest { + keyspace: string; + name: string; + start: number; + stop: number; +} + +export interface LRangeResponse { + items: Buffer[]; +} + +export interface HSetRequest { + keyspace: string; + name: string; + field: Buffer; + value: Buffer; +} + +export interface HSetResponse { +} + +export interface HGetRequest { + keyspace: string; + name: string; + field: Buffer; +} + +export interface HGetResponse { + present: boolean; + value: Buffer; +} + +export interface HDelRequest { + keyspace: string; + name: string; + field: Buffer; +} + +export interface HDelResponse { +} + +export interface HExistsRequest { + keyspace: string; + name: string; + field: Buffer; +} + +export interface HExistsResponse { + present: boolean; +} + +export interface HLenRequest { + keyspace: string; + name: string; +} + +export interface HLenResponse { + len: number; +} + +export interface HGetAllRequest { + keyspace: string; + name: string; +} + +export interface HashField { + field: Buffer; + value: Buffer; +} + +export interface HGetAllResponse { + fields: HashField[]; +} + +export interface IncrRequest { + keyspace: string; + name: string; + delta: number; +} + +export interface IncrResponse { + value: number; +} + +export interface CounterGetRequest { + keyspace: string; + name: string; +} + +export interface CounterGetResponse { + present: boolean; + value: number; +} + +export interface JsonSetRequest { + keyspace: string; + name: string; + path: string; + value: Buffer; +} + +export interface JsonSetResponse { +} + +export interface JsonGetRequest { + keyspace: string; + name: string; + path: string; +} + +export interface JsonGetResponse { + present: boolean; + value: Buffer; +} + +export interface JsonDelRequest { + keyspace: string; + name: string; + path: string; +} + +export interface JsonDelResponse { +} + +export interface BitSetRequest { + keyspace: string; + name: string; + offset: number; + bit: boolean; +} + +export interface BitSetResponse { +} + +export interface BitGetRequest { + keyspace: string; + name: string; + offset: number; +} + +export interface BitGetResponse { + present: boolean; + bit: boolean; +} + +export interface BitCountRequest { + keyspace: string; + name: string; + start: number; + end: number; +} + +export interface BitCountResponse { + count: number; +} + +export interface BitPosRequest { + keyspace: string; + name: string; + bit: boolean; + start: number; + end: number; +} + +export interface BitPosResponse { + found: boolean; + pos: number; +} + +export interface HLLAddRequest { + keyspace: string; + name: string; + item: Buffer; +} + +export interface HLLAddResponse { +} + +export interface HLLCountRequest { + keyspace: string; + name: string; +} + +export interface HLLCountResponse { + present: boolean; + count: number; +} + +export interface TopKAddRequest { + keyspace: string; + name: string; + item: Buffer; +} + +export interface TopKAddResponse { +} + +export interface TopKListRequest { + keyspace: string; + name: string; +} + +export interface TopKEntry { + item: Buffer; + count: number; +} + +export interface TopKListResponse { + present: boolean; + entries: TopKEntry[]; +} + +export interface CMSIncrRequest { + keyspace: string; + name: string; + item: Buffer; + /** 0 means 1 */ + n: number; +} + +export interface CMSIncrResponse { +} + +export interface CMSQueryRequest { + keyspace: string; + name: string; + item: Buffer; +} + +export interface CMSQueryResponse { + present: boolean; + count: number; +} + +export interface VAddRequest { + keyspace: string; + name: string; + member: Buffer; + vec: number[]; +} + +export interface VAddResponse { +} + +export interface VRemRequest { + keyspace: string; + name: string; + member: Buffer; +} + +export interface VRemResponse { +} + +export interface VSimRequest { + keyspace: string; + name: string; + vec: number[]; + k: number; +} + +export interface VSimHit { + member: Buffer; + score: number; +} + +export interface VSimResponse { + hits: VSimHit[]; +} + +export interface VCardRequest { + keyspace: string; + name: string; +} + +export interface VCardResponse { + n: number; + present: boolean; +} + +export interface VDimRequest { + keyspace: string; + name: string; +} + +export interface VDimResponse { + dim: number; + present: boolean; +} + +export interface VEmbRequest { + keyspace: string; + name: string; + member: Buffer; +} + +export interface VEmbResponse { + vec: number[]; + found: boolean; +} + +export interface StreamEntry { + id: string; + payload: Buffer; +} + +export interface XAddRequest { + keyspace: string; + name: string; + payload: Buffer; +} + +export interface XAddResponse { + id: string; +} + +export interface XRangeRequest { + keyspace: string; + name: string; + start: string; + end: string; + count: number; +} + +export interface XRevRangeRequest { + keyspace: string; + name: string; + start: string; + end: string; + count: number; +} + +export interface XRangeResponse { + entries: StreamEntry[]; +} + +export interface XLenRequest { + keyspace: string; + name: string; +} + +export interface XLenResponse { + n: number; + present: boolean; +} + +export interface XDelRequest { + keyspace: string; + name: string; + id: string; +} + +export interface XDelResponse { +} + +export interface XTrimRequest { + keyspace: string; + name: string; + maxLen: number; +} + +export interface XTrimResponse { +} + +function createBaseGetRequest(): GetRequest { + return { keyspace: "", key: "" }; +} + +export const GetRequest: MessageFns = { + encode(message: GetRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.key !== "") { + writer.uint32(18).string(message.key); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GetRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGetRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.key = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GetRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + key: isSet(object.key) ? globalThis.String(object.key) : "", + }; + }, + + toJSON(message: GetRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.key !== "") { + obj.key = message.key; + } + return obj; + }, + + create(base?: DeepPartial): GetRequest { + return GetRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GetRequest { + const message = createBaseGetRequest(); + message.keyspace = object.keyspace ?? ""; + message.key = object.key ?? ""; + return message; + }, +}; + +function createBaseGetResponse(): GetResponse { + return { found: false, value: Buffer.alloc(0) }; +} + +export const GetResponse: MessageFns = { + encode(message: GetResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.found !== false) { + writer.uint32(8).bool(message.found); + } + if (message.value.length !== 0) { + writer.uint32(18).bytes(message.value); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GetResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGetResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.found = reader.bool(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.value = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GetResponse { + return { + found: isSet(object.found) ? globalThis.Boolean(object.found) : false, + value: isSet(object.value) ? Buffer.from(bytesFromBase64(object.value)) : Buffer.alloc(0), + }; + }, + + toJSON(message: GetResponse): unknown { + const obj: any = {}; + if (message.found !== false) { + obj.found = message.found; + } + if (message.value.length !== 0) { + obj.value = base64FromBytes(message.value); + } + return obj; + }, + + create(base?: DeepPartial): GetResponse { + return GetResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GetResponse { + const message = createBaseGetResponse(); + message.found = object.found ?? false; + message.value = object.value ?? Buffer.alloc(0); + return message; + }, +}; + +function createBasePutRequest(): PutRequest { + return { keyspace: "", key: "", value: Buffer.alloc(0), ttlNanos: 0, ttlSet: false }; +} + +export const PutRequest: MessageFns = { + encode(message: PutRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.key !== "") { + writer.uint32(18).string(message.key); + } + if (message.value.length !== 0) { + writer.uint32(26).bytes(message.value); + } + if (message.ttlNanos !== 0) { + writer.uint32(32).int64(message.ttlNanos); + } + if (message.ttlSet !== false) { + writer.uint32(40).bool(message.ttlSet); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PutRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePutRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.key = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.value = Buffer.from(reader.bytes()); + continue; + } + case 4: { + if (tag !== 32) { + break; + } + + message.ttlNanos = longToNumber(reader.int64()); + continue; + } + case 5: { + if (tag !== 40) { + break; + } + + message.ttlSet = reader.bool(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PutRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + key: isSet(object.key) ? globalThis.String(object.key) : "", + value: isSet(object.value) ? Buffer.from(bytesFromBase64(object.value)) : Buffer.alloc(0), + ttlNanos: isSet(object.ttlNanos) ? globalThis.Number(object.ttlNanos) : 0, + ttlSet: isSet(object.ttlSet) ? globalThis.Boolean(object.ttlSet) : false, + }; + }, + + toJSON(message: PutRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.key !== "") { + obj.key = message.key; + } + if (message.value.length !== 0) { + obj.value = base64FromBytes(message.value); + } + if (message.ttlNanos !== 0) { + obj.ttlNanos = Math.round(message.ttlNanos); + } + if (message.ttlSet !== false) { + obj.ttlSet = message.ttlSet; + } + return obj; + }, + + create(base?: DeepPartial): PutRequest { + return PutRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): PutRequest { + const message = createBasePutRequest(); + message.keyspace = object.keyspace ?? ""; + message.key = object.key ?? ""; + message.value = object.value ?? Buffer.alloc(0); + message.ttlNanos = object.ttlNanos ?? 0; + message.ttlSet = object.ttlSet ?? false; + return message; + }, +}; + +function createBasePutResponse(): PutResponse { + return {}; +} + +export const PutResponse: MessageFns = { + encode(_: PutResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PutResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePutResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): PutResponse { + return {}; + }, + + toJSON(_: PutResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): PutResponse { + return PutResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): PutResponse { + const message = createBasePutResponse(); + return message; + }, +}; + +function createBaseKV(): KV { + return { key: "", value: Buffer.alloc(0) }; +} + +export const KV: MessageFns = { + encode(message: KV, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.key !== "") { + writer.uint32(10).string(message.key); + } + if (message.value.length !== 0) { + writer.uint32(18).bytes(message.value); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): KV { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseKV(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.key = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.value = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): KV { + return { + key: isSet(object.key) ? globalThis.String(object.key) : "", + value: isSet(object.value) ? Buffer.from(bytesFromBase64(object.value)) : Buffer.alloc(0), + }; + }, + + toJSON(message: KV): unknown { + const obj: any = {}; + if (message.key !== "") { + obj.key = message.key; + } + if (message.value.length !== 0) { + obj.value = base64FromBytes(message.value); + } + return obj; + }, + + create(base?: DeepPartial): KV { + return KV.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): KV { + const message = createBaseKV(); + message.key = object.key ?? ""; + message.value = object.value ?? Buffer.alloc(0); + return message; + }, +}; + +function createBasePutManyRequest(): PutManyRequest { + return { keyspace: "", items: [], ttlNanos: 0, ttlSet: false }; +} + +export const PutManyRequest: MessageFns = { + encode(message: PutManyRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + for (const v of message.items) { + KV.encode(v!, writer.uint32(18).fork()).join(); + } + if (message.ttlNanos !== 0) { + writer.uint32(24).int64(message.ttlNanos); + } + if (message.ttlSet !== false) { + writer.uint32(32).bool(message.ttlSet); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PutManyRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePutManyRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.items.push(KV.decode(reader, reader.uint32())); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.ttlNanos = longToNumber(reader.int64()); + continue; + } + case 4: { + if (tag !== 32) { + break; + } + + message.ttlSet = reader.bool(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PutManyRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + items: globalThis.Array.isArray(object?.items) ? object.items.map((e: any) => KV.fromJSON(e)) : [], + ttlNanos: isSet(object.ttlNanos) ? globalThis.Number(object.ttlNanos) : 0, + ttlSet: isSet(object.ttlSet) ? globalThis.Boolean(object.ttlSet) : false, + }; + }, + + toJSON(message: PutManyRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.items?.length) { + obj.items = message.items.map((e) => KV.toJSON(e)); + } + if (message.ttlNanos !== 0) { + obj.ttlNanos = Math.round(message.ttlNanos); + } + if (message.ttlSet !== false) { + obj.ttlSet = message.ttlSet; + } + return obj; + }, + + create(base?: DeepPartial): PutManyRequest { + return PutManyRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): PutManyRequest { + const message = createBasePutManyRequest(); + message.keyspace = object.keyspace ?? ""; + message.items = object.items?.map((e) => KV.fromPartial(e)) || []; + message.ttlNanos = object.ttlNanos ?? 0; + message.ttlSet = object.ttlSet ?? false; + return message; + }, +}; + +function createBaseKeyError(): KeyError { + return { key: "", message: "", peerFailures: [] }; +} + +export const KeyError: MessageFns = { + encode(message: KeyError, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.key !== "") { + writer.uint32(10).string(message.key); + } + if (message.message !== "") { + writer.uint32(18).string(message.message); + } + for (const v of message.peerFailures) { + PeerFailure.encode(v!, writer.uint32(26).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): KeyError { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseKeyError(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.key = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.message = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.peerFailures.push(PeerFailure.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): KeyError { + return { + key: isSet(object.key) ? globalThis.String(object.key) : "", + message: isSet(object.message) ? globalThis.String(object.message) : "", + peerFailures: globalThis.Array.isArray(object?.peerFailures) + ? object.peerFailures.map((e: any) => PeerFailure.fromJSON(e)) + : [], + }; + }, + + toJSON(message: KeyError): unknown { + const obj: any = {}; + if (message.key !== "") { + obj.key = message.key; + } + if (message.message !== "") { + obj.message = message.message; + } + if (message.peerFailures?.length) { + obj.peerFailures = message.peerFailures.map((e) => PeerFailure.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): KeyError { + return KeyError.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): KeyError { + const message = createBaseKeyError(); + message.key = object.key ?? ""; + message.message = object.message ?? ""; + message.peerFailures = object.peerFailures?.map((e) => PeerFailure.fromPartial(e)) || []; + return message; + }, +}; + +function createBasePutManyResponse(): PutManyResponse { + return { errors: [] }; +} + +export const PutManyResponse: MessageFns = { + encode(message: PutManyResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.errors) { + KeyError.encode(v!, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PutManyResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePutManyResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.errors.push(KeyError.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PutManyResponse { + return { + errors: globalThis.Array.isArray(object?.errors) ? object.errors.map((e: any) => KeyError.fromJSON(e)) : [], + }; + }, + + toJSON(message: PutManyResponse): unknown { + const obj: any = {}; + if (message.errors?.length) { + obj.errors = message.errors.map((e) => KeyError.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): PutManyResponse { + return PutManyResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): PutManyResponse { + const message = createBasePutManyResponse(); + message.errors = object.errors?.map((e) => KeyError.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseDeleteRequest(): DeleteRequest { + return { keyspace: "", key: "" }; +} + +export const DeleteRequest: MessageFns = { + encode(message: DeleteRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.key !== "") { + writer.uint32(18).string(message.key); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): DeleteRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDeleteRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.key = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): DeleteRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + key: isSet(object.key) ? globalThis.String(object.key) : "", + }; + }, + + toJSON(message: DeleteRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.key !== "") { + obj.key = message.key; + } + return obj; + }, + + create(base?: DeepPartial): DeleteRequest { + return DeleteRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): DeleteRequest { + const message = createBaseDeleteRequest(); + message.keyspace = object.keyspace ?? ""; + message.key = object.key ?? ""; + return message; + }, +}; + +function createBasePeerFailure(): PeerFailure { + return { peerId: "", message: "" }; +} + +export const PeerFailure: MessageFns = { + encode(message: PeerFailure, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.peerId !== "") { + writer.uint32(10).string(message.peerId); + } + if (message.message !== "") { + writer.uint32(18).string(message.message); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PeerFailure { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePeerFailure(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.peerId = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.message = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PeerFailure { + return { + peerId: isSet(object.peerId) ? globalThis.String(object.peerId) : "", + message: isSet(object.message) ? globalThis.String(object.message) : "", + }; + }, + + toJSON(message: PeerFailure): unknown { + const obj: any = {}; + if (message.peerId !== "") { + obj.peerId = message.peerId; + } + if (message.message !== "") { + obj.message = message.message; + } + return obj; + }, + + create(base?: DeepPartial): PeerFailure { + return PeerFailure.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): PeerFailure { + const message = createBasePeerFailure(); + message.peerId = object.peerId ?? ""; + message.message = object.message ?? ""; + return message; + }, +}; + +function createBaseDeleteResponse(): DeleteResponse { + return { peerFailures: [] }; +} + +export const DeleteResponse: MessageFns = { + encode(message: DeleteResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.peerFailures) { + PeerFailure.encode(v!, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): DeleteResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDeleteResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.peerFailures.push(PeerFailure.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): DeleteResponse { + return { + peerFailures: globalThis.Array.isArray(object?.peerFailures) + ? object.peerFailures.map((e: any) => PeerFailure.fromJSON(e)) + : [], + }; + }, + + toJSON(message: DeleteResponse): unknown { + const obj: any = {}; + if (message.peerFailures?.length) { + obj.peerFailures = message.peerFailures.map((e) => PeerFailure.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): DeleteResponse { + return DeleteResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): DeleteResponse { + const message = createBaseDeleteResponse(); + message.peerFailures = object.peerFailures?.map((e) => PeerFailure.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseDeleteManyRequest(): DeleteManyRequest { + return { keyspace: "", keys: [] }; +} + +export const DeleteManyRequest: MessageFns = { + encode(message: DeleteManyRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + for (const v of message.keys) { + writer.uint32(18).string(v!); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): DeleteManyRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDeleteManyRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.keys.push(reader.string()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): DeleteManyRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + keys: globalThis.Array.isArray(object?.keys) ? object.keys.map((e: any) => globalThis.String(e)) : [], + }; + }, + + toJSON(message: DeleteManyRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.keys?.length) { + obj.keys = message.keys; + } + return obj; + }, + + create(base?: DeepPartial): DeleteManyRequest { + return DeleteManyRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): DeleteManyRequest { + const message = createBaseDeleteManyRequest(); + message.keyspace = object.keyspace ?? ""; + message.keys = object.keys?.map((e) => e) || []; + return message; + }, +}; + +function createBaseDeleteManyResponse(): DeleteManyResponse { + return { errors: [] }; +} + +export const DeleteManyResponse: MessageFns = { + encode(message: DeleteManyResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.errors) { + KeyError.encode(v!, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): DeleteManyResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDeleteManyResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.errors.push(KeyError.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): DeleteManyResponse { + return { + errors: globalThis.Array.isArray(object?.errors) ? object.errors.map((e: any) => KeyError.fromJSON(e)) : [], + }; + }, + + toJSON(message: DeleteManyResponse): unknown { + const obj: any = {}; + if (message.errors?.length) { + obj.errors = message.errors.map((e) => KeyError.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): DeleteManyResponse { + return DeleteManyResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): DeleteManyResponse { + const message = createBaseDeleteManyResponse(); + message.errors = object.errors?.map((e) => KeyError.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseBloomAddRequest(): BloomAddRequest { + return { keyspace: "", name: "", item: Buffer.alloc(0) }; +} + +export const BloomAddRequest: MessageFns = { + encode(message: BloomAddRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.item.length !== 0) { + writer.uint32(26).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): BloomAddRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBloomAddRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): BloomAddRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: BloomAddRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): BloomAddRequest { + return BloomAddRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): BloomAddRequest { + const message = createBaseBloomAddRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseBloomAddResponse(): BloomAddResponse { + return {}; +} + +export const BloomAddResponse: MessageFns = { + encode(_: BloomAddResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): BloomAddResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBloomAddResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): BloomAddResponse { + return {}; + }, + + toJSON(_: BloomAddResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): BloomAddResponse { + return BloomAddResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): BloomAddResponse { + const message = createBaseBloomAddResponse(); + return message; + }, +}; + +function createBaseBloomTestRequest(): BloomTestRequest { + return { keyspace: "", name: "", item: Buffer.alloc(0) }; +} + +export const BloomTestRequest: MessageFns = { + encode(message: BloomTestRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.item.length !== 0) { + writer.uint32(26).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): BloomTestRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBloomTestRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): BloomTestRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: BloomTestRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): BloomTestRequest { + return BloomTestRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): BloomTestRequest { + const message = createBaseBloomTestRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseBloomTestResponse(): BloomTestResponse { + return { maybe: false }; +} + +export const BloomTestResponse: MessageFns = { + encode(message: BloomTestResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.maybe !== false) { + writer.uint32(8).bool(message.maybe); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): BloomTestResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBloomTestResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.maybe = reader.bool(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): BloomTestResponse { + return { maybe: isSet(object.maybe) ? globalThis.Boolean(object.maybe) : false }; + }, + + toJSON(message: BloomTestResponse): unknown { + const obj: any = {}; + if (message.maybe !== false) { + obj.maybe = message.maybe; + } + return obj; + }, + + create(base?: DeepPartial): BloomTestResponse { + return BloomTestResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): BloomTestResponse { + const message = createBaseBloomTestResponse(); + message.maybe = object.maybe ?? false; + return message; + }, +}; + +function createBaseSetAddRequest(): SetAddRequest { + return { keyspace: "", name: "", item: Buffer.alloc(0) }; +} + +export const SetAddRequest: MessageFns = { + encode(message: SetAddRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.item.length !== 0) { + writer.uint32(26).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SetAddRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSetAddRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SetAddRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: SetAddRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): SetAddRequest { + return SetAddRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): SetAddRequest { + const message = createBaseSetAddRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseSetAddResponse(): SetAddResponse { + return {}; +} + +export const SetAddResponse: MessageFns = { + encode(_: SetAddResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SetAddResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSetAddResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): SetAddResponse { + return {}; + }, + + toJSON(_: SetAddResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): SetAddResponse { + return SetAddResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): SetAddResponse { + const message = createBaseSetAddResponse(); + return message; + }, +}; + +function createBaseSetRemoveRequest(): SetRemoveRequest { + return { keyspace: "", name: "", item: Buffer.alloc(0) }; +} + +export const SetRemoveRequest: MessageFns = { + encode(message: SetRemoveRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.item.length !== 0) { + writer.uint32(26).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SetRemoveRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSetRemoveRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SetRemoveRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: SetRemoveRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): SetRemoveRequest { + return SetRemoveRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): SetRemoveRequest { + const message = createBaseSetRemoveRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseSetRemoveResponse(): SetRemoveResponse { + return {}; +} + +export const SetRemoveResponse: MessageFns = { + encode(_: SetRemoveResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SetRemoveResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSetRemoveResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): SetRemoveResponse { + return {}; + }, + + toJSON(_: SetRemoveResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): SetRemoveResponse { + return SetRemoveResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): SetRemoveResponse { + const message = createBaseSetRemoveResponse(); + return message; + }, +}; + +function createBaseSetContainsRequest(): SetContainsRequest { + return { keyspace: "", name: "", item: Buffer.alloc(0) }; +} + +export const SetContainsRequest: MessageFns = { + encode(message: SetContainsRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.item.length !== 0) { + writer.uint32(26).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SetContainsRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSetContainsRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SetContainsRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: SetContainsRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): SetContainsRequest { + return SetContainsRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): SetContainsRequest { + const message = createBaseSetContainsRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseSetContainsResponse(): SetContainsResponse { + return { present: false }; +} + +export const SetContainsResponse: MessageFns = { + encode(message: SetContainsResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SetContainsResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSetContainsResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SetContainsResponse { + return { present: isSet(object.present) ? globalThis.Boolean(object.present) : false }; + }, + + toJSON(message: SetContainsResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + return obj; + }, + + create(base?: DeepPartial): SetContainsResponse { + return SetContainsResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): SetContainsResponse { + const message = createBaseSetContainsResponse(); + message.present = object.present ?? false; + return message; + }, +}; + +function createBaseSetCardRequest(): SetCardRequest { + return { keyspace: "", name: "" }; +} + +export const SetCardRequest: MessageFns = { + encode(message: SetCardRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SetCardRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSetCardRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SetCardRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: SetCardRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): SetCardRequest { + return SetCardRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): SetCardRequest { + const message = createBaseSetCardRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseSetCardResponse(): SetCardResponse { + return { card: 0 }; +} + +export const SetCardResponse: MessageFns = { + encode(message: SetCardResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.card !== 0) { + writer.uint32(8).int64(message.card); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SetCardResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSetCardResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.card = longToNumber(reader.int64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SetCardResponse { + return { card: isSet(object.card) ? globalThis.Number(object.card) : 0 }; + }, + + toJSON(message: SetCardResponse): unknown { + const obj: any = {}; + if (message.card !== 0) { + obj.card = Math.round(message.card); + } + return obj; + }, + + create(base?: DeepPartial): SetCardResponse { + return SetCardResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): SetCardResponse { + const message = createBaseSetCardResponse(); + message.card = object.card ?? 0; + return message; + }, +}; + +function createBaseSetMembersRequest(): SetMembersRequest { + return { keyspace: "", name: "" }; +} + +export const SetMembersRequest: MessageFns = { + encode(message: SetMembersRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SetMembersRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSetMembersRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SetMembersRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: SetMembersRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): SetMembersRequest { + return SetMembersRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): SetMembersRequest { + const message = createBaseSetMembersRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseSetMembersResponse(): SetMembersResponse { + return { members: [] }; +} + +export const SetMembersResponse: MessageFns = { + encode(message: SetMembersResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.members) { + writer.uint32(10).bytes(v!); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): SetMembersResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSetMembersResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.members.push(Buffer.from(reader.bytes())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): SetMembersResponse { + return { + members: globalThis.Array.isArray(object?.members) + ? object.members.map((e: any) => Buffer.from(bytesFromBase64(e))) + : [], + }; + }, + + toJSON(message: SetMembersResponse): unknown { + const obj: any = {}; + if (message.members?.length) { + obj.members = message.members.map((e) => base64FromBytes(e)); + } + return obj; + }, + + create(base?: DeepPartial): SetMembersResponse { + return SetMembersResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): SetMembersResponse { + const message = createBaseSetMembersResponse(); + message.members = object.members?.map((e) => e) || []; + return message; + }, +}; + +function createBaseZMember(): ZMember { + return { member: Buffer.alloc(0), score: 0 }; +} + +export const ZMember: MessageFns = { + encode(message: ZMember, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.member.length !== 0) { + writer.uint32(10).bytes(message.member); + } + if (message.score !== 0) { + writer.uint32(17).double(message.score); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ZMember { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZMember(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.member = Buffer.from(reader.bytes()); + continue; + } + case 2: { + if (tag !== 17) { + break; + } + + message.score = reader.double(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ZMember { + return { + member: isSet(object.member) ? Buffer.from(bytesFromBase64(object.member)) : Buffer.alloc(0), + score: isSet(object.score) ? globalThis.Number(object.score) : 0, + }; + }, + + toJSON(message: ZMember): unknown { + const obj: any = {}; + if (message.member.length !== 0) { + obj.member = base64FromBytes(message.member); + } + if (message.score !== 0) { + obj.score = message.score; + } + return obj; + }, + + create(base?: DeepPartial): ZMember { + return ZMember.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ZMember { + const message = createBaseZMember(); + message.member = object.member ?? Buffer.alloc(0); + message.score = object.score ?? 0; + return message; + }, +}; + +function createBaseZAddRequest(): ZAddRequest { + return { keyspace: "", name: "", member: Buffer.alloc(0), score: 0 }; +} + +export const ZAddRequest: MessageFns = { + encode(message: ZAddRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.member.length !== 0) { + writer.uint32(26).bytes(message.member); + } + if (message.score !== 0) { + writer.uint32(33).double(message.score); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ZAddRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZAddRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.member = Buffer.from(reader.bytes()); + continue; + } + case 4: { + if (tag !== 33) { + break; + } + + message.score = reader.double(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ZAddRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + member: isSet(object.member) ? Buffer.from(bytesFromBase64(object.member)) : Buffer.alloc(0), + score: isSet(object.score) ? globalThis.Number(object.score) : 0, + }; + }, + + toJSON(message: ZAddRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.member.length !== 0) { + obj.member = base64FromBytes(message.member); + } + if (message.score !== 0) { + obj.score = message.score; + } + return obj; + }, + + create(base?: DeepPartial): ZAddRequest { + return ZAddRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ZAddRequest { + const message = createBaseZAddRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.member = object.member ?? Buffer.alloc(0); + message.score = object.score ?? 0; + return message; + }, +}; + +function createBaseZAddResponse(): ZAddResponse { + return {}; +} + +export const ZAddResponse: MessageFns = { + encode(_: ZAddResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ZAddResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZAddResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): ZAddResponse { + return {}; + }, + + toJSON(_: ZAddResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): ZAddResponse { + return ZAddResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): ZAddResponse { + const message = createBaseZAddResponse(); + return message; + }, +}; + +function createBaseZRemRequest(): ZRemRequest { + return { keyspace: "", name: "", member: Buffer.alloc(0) }; +} + +export const ZRemRequest: MessageFns = { + encode(message: ZRemRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.member.length !== 0) { + writer.uint32(26).bytes(message.member); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ZRemRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZRemRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.member = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ZRemRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + member: isSet(object.member) ? Buffer.from(bytesFromBase64(object.member)) : Buffer.alloc(0), + }; + }, + + toJSON(message: ZRemRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.member.length !== 0) { + obj.member = base64FromBytes(message.member); + } + return obj; + }, + + create(base?: DeepPartial): ZRemRequest { + return ZRemRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ZRemRequest { + const message = createBaseZRemRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.member = object.member ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseZRemResponse(): ZRemResponse { + return {}; +} + +export const ZRemResponse: MessageFns = { + encode(_: ZRemResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ZRemResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZRemResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): ZRemResponse { + return {}; + }, + + toJSON(_: ZRemResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): ZRemResponse { + return ZRemResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): ZRemResponse { + const message = createBaseZRemResponse(); + return message; + }, +}; + +function createBaseZScoreRequest(): ZScoreRequest { + return { keyspace: "", name: "", member: Buffer.alloc(0) }; +} + +export const ZScoreRequest: MessageFns = { + encode(message: ZScoreRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.member.length !== 0) { + writer.uint32(26).bytes(message.member); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ZScoreRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZScoreRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.member = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ZScoreRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + member: isSet(object.member) ? Buffer.from(bytesFromBase64(object.member)) : Buffer.alloc(0), + }; + }, + + toJSON(message: ZScoreRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.member.length !== 0) { + obj.member = base64FromBytes(message.member); + } + return obj; + }, + + create(base?: DeepPartial): ZScoreRequest { + return ZScoreRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ZScoreRequest { + const message = createBaseZScoreRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.member = object.member ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseZScoreResponse(): ZScoreResponse { + return { present: false, score: 0 }; +} + +export const ZScoreResponse: MessageFns = { + encode(message: ZScoreResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + if (message.score !== 0) { + writer.uint32(17).double(message.score); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ZScoreResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZScoreResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 17) { + break; + } + + message.score = reader.double(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ZScoreResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + score: isSet(object.score) ? globalThis.Number(object.score) : 0, + }; + }, + + toJSON(message: ZScoreResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.score !== 0) { + obj.score = message.score; + } + return obj; + }, + + create(base?: DeepPartial): ZScoreResponse { + return ZScoreResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ZScoreResponse { + const message = createBaseZScoreResponse(); + message.present = object.present ?? false; + message.score = object.score ?? 0; + return message; + }, +}; + +function createBaseZCardRequest(): ZCardRequest { + return { keyspace: "", name: "" }; +} + +export const ZCardRequest: MessageFns = { + encode(message: ZCardRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ZCardRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZCardRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ZCardRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: ZCardRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): ZCardRequest { + return ZCardRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ZCardRequest { + const message = createBaseZCardRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseZCardResponse(): ZCardResponse { + return { card: 0 }; +} + +export const ZCardResponse: MessageFns = { + encode(message: ZCardResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.card !== 0) { + writer.uint32(8).int64(message.card); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ZCardResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZCardResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.card = longToNumber(reader.int64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ZCardResponse { + return { card: isSet(object.card) ? globalThis.Number(object.card) : 0 }; + }, + + toJSON(message: ZCardResponse): unknown { + const obj: any = {}; + if (message.card !== 0) { + obj.card = Math.round(message.card); + } + return obj; + }, + + create(base?: DeepPartial): ZCardResponse { + return ZCardResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ZCardResponse { + const message = createBaseZCardResponse(); + message.card = object.card ?? 0; + return message; + }, +}; + +function createBaseZRangeRequest(): ZRangeRequest { + return { keyspace: "", name: "", start: 0, stop: 0 }; +} + +export const ZRangeRequest: MessageFns = { + encode(message: ZRangeRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.start !== 0) { + writer.uint32(24).int32(message.start); + } + if (message.stop !== 0) { + writer.uint32(32).int32(message.stop); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ZRangeRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZRangeRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.start = reader.int32(); + continue; + } + case 4: { + if (tag !== 32) { + break; + } + + message.stop = reader.int32(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ZRangeRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + start: isSet(object.start) ? globalThis.Number(object.start) : 0, + stop: isSet(object.stop) ? globalThis.Number(object.stop) : 0, + }; + }, + + toJSON(message: ZRangeRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.start !== 0) { + obj.start = Math.round(message.start); + } + if (message.stop !== 0) { + obj.stop = Math.round(message.stop); + } + return obj; + }, + + create(base?: DeepPartial): ZRangeRequest { + return ZRangeRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ZRangeRequest { + const message = createBaseZRangeRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.start = object.start ?? 0; + message.stop = object.stop ?? 0; + return message; + }, +}; + +function createBaseZRangeByScoreRequest(): ZRangeByScoreRequest { + return { keyspace: "", name: "", min: 0, max: 0 }; +} + +export const ZRangeByScoreRequest: MessageFns = { + encode(message: ZRangeByScoreRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.min !== 0) { + writer.uint32(25).double(message.min); + } + if (message.max !== 0) { + writer.uint32(33).double(message.max); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ZRangeByScoreRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZRangeByScoreRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 25) { + break; + } + + message.min = reader.double(); + continue; + } + case 4: { + if (tag !== 33) { + break; + } + + message.max = reader.double(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ZRangeByScoreRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + min: isSet(object.min) ? globalThis.Number(object.min) : 0, + max: isSet(object.max) ? globalThis.Number(object.max) : 0, + }; + }, + + toJSON(message: ZRangeByScoreRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.min !== 0) { + obj.min = message.min; + } + if (message.max !== 0) { + obj.max = message.max; + } + return obj; + }, + + create(base?: DeepPartial): ZRangeByScoreRequest { + return ZRangeByScoreRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ZRangeByScoreRequest { + const message = createBaseZRangeByScoreRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.min = object.min ?? 0; + message.max = object.max ?? 0; + return message; + }, +}; + +function createBaseZRangeResponse(): ZRangeResponse { + return { members: [] }; +} + +export const ZRangeResponse: MessageFns = { + encode(message: ZRangeResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.members) { + ZMember.encode(v!, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): ZRangeResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseZRangeResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.members.push(ZMember.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): ZRangeResponse { + return { + members: globalThis.Array.isArray(object?.members) ? object.members.map((e: any) => ZMember.fromJSON(e)) : [], + }; + }, + + toJSON(message: ZRangeResponse): unknown { + const obj: any = {}; + if (message.members?.length) { + obj.members = message.members.map((e) => ZMember.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): ZRangeResponse { + return ZRangeResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): ZRangeResponse { + const message = createBaseZRangeResponse(); + message.members = object.members?.map((e) => ZMember.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseGeoMember(): GeoMember { + return { member: Buffer.alloc(0), lon: 0, lat: 0, distMeters: 0 }; +} + +export const GeoMember: MessageFns = { + encode(message: GeoMember, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.member.length !== 0) { + writer.uint32(10).bytes(message.member); + } + if (message.lon !== 0) { + writer.uint32(17).double(message.lon); + } + if (message.lat !== 0) { + writer.uint32(25).double(message.lat); + } + if (message.distMeters !== 0) { + writer.uint32(33).double(message.distMeters); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoMember { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoMember(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.member = Buffer.from(reader.bytes()); + continue; + } + case 2: { + if (tag !== 17) { + break; + } + + message.lon = reader.double(); + continue; + } + case 3: { + if (tag !== 25) { + break; + } + + message.lat = reader.double(); + continue; + } + case 4: { + if (tag !== 33) { + break; + } + + message.distMeters = reader.double(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GeoMember { + return { + member: isSet(object.member) ? Buffer.from(bytesFromBase64(object.member)) : Buffer.alloc(0), + lon: isSet(object.lon) ? globalThis.Number(object.lon) : 0, + lat: isSet(object.lat) ? globalThis.Number(object.lat) : 0, + distMeters: isSet(object.distMeters) ? globalThis.Number(object.distMeters) : 0, + }; + }, + + toJSON(message: GeoMember): unknown { + const obj: any = {}; + if (message.member.length !== 0) { + obj.member = base64FromBytes(message.member); + } + if (message.lon !== 0) { + obj.lon = message.lon; + } + if (message.lat !== 0) { + obj.lat = message.lat; + } + if (message.distMeters !== 0) { + obj.distMeters = message.distMeters; + } + return obj; + }, + + create(base?: DeepPartial): GeoMember { + return GeoMember.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GeoMember { + const message = createBaseGeoMember(); + message.member = object.member ?? Buffer.alloc(0); + message.lon = object.lon ?? 0; + message.lat = object.lat ?? 0; + message.distMeters = object.distMeters ?? 0; + return message; + }, +}; + +function createBaseGeoAddRequest(): GeoAddRequest { + return { keyspace: "", name: "", member: Buffer.alloc(0), lon: 0, lat: 0 }; +} + +export const GeoAddRequest: MessageFns = { + encode(message: GeoAddRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.member.length !== 0) { + writer.uint32(26).bytes(message.member); + } + if (message.lon !== 0) { + writer.uint32(33).double(message.lon); + } + if (message.lat !== 0) { + writer.uint32(41).double(message.lat); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoAddRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoAddRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.member = Buffer.from(reader.bytes()); + continue; + } + case 4: { + if (tag !== 33) { + break; + } + + message.lon = reader.double(); + continue; + } + case 5: { + if (tag !== 41) { + break; + } + + message.lat = reader.double(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GeoAddRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + member: isSet(object.member) ? Buffer.from(bytesFromBase64(object.member)) : Buffer.alloc(0), + lon: isSet(object.lon) ? globalThis.Number(object.lon) : 0, + lat: isSet(object.lat) ? globalThis.Number(object.lat) : 0, + }; + }, + + toJSON(message: GeoAddRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.member.length !== 0) { + obj.member = base64FromBytes(message.member); + } + if (message.lon !== 0) { + obj.lon = message.lon; + } + if (message.lat !== 0) { + obj.lat = message.lat; + } + return obj; + }, + + create(base?: DeepPartial): GeoAddRequest { + return GeoAddRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GeoAddRequest { + const message = createBaseGeoAddRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.member = object.member ?? Buffer.alloc(0); + message.lon = object.lon ?? 0; + message.lat = object.lat ?? 0; + return message; + }, +}; + +function createBaseGeoAddResponse(): GeoAddResponse { + return {}; +} + +export const GeoAddResponse: MessageFns = { + encode(_: GeoAddResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoAddResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoAddResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): GeoAddResponse { + return {}; + }, + + toJSON(_: GeoAddResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): GeoAddResponse { + return GeoAddResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): GeoAddResponse { + const message = createBaseGeoAddResponse(); + return message; + }, +}; + +function createBaseGeoRemRequest(): GeoRemRequest { + return { keyspace: "", name: "", member: Buffer.alloc(0) }; +} + +export const GeoRemRequest: MessageFns = { + encode(message: GeoRemRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.member.length !== 0) { + writer.uint32(26).bytes(message.member); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoRemRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoRemRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.member = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GeoRemRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + member: isSet(object.member) ? Buffer.from(bytesFromBase64(object.member)) : Buffer.alloc(0), + }; + }, + + toJSON(message: GeoRemRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.member.length !== 0) { + obj.member = base64FromBytes(message.member); + } + return obj; + }, + + create(base?: DeepPartial): GeoRemRequest { + return GeoRemRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GeoRemRequest { + const message = createBaseGeoRemRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.member = object.member ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseGeoRemResponse(): GeoRemResponse { + return {}; +} + +export const GeoRemResponse: MessageFns = { + encode(_: GeoRemResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoRemResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoRemResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): GeoRemResponse { + return {}; + }, + + toJSON(_: GeoRemResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): GeoRemResponse { + return GeoRemResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): GeoRemResponse { + const message = createBaseGeoRemResponse(); + return message; + }, +}; + +function createBaseGeoPosRequest(): GeoPosRequest { + return { keyspace: "", name: "", member: Buffer.alloc(0) }; +} + +export const GeoPosRequest: MessageFns = { + encode(message: GeoPosRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.member.length !== 0) { + writer.uint32(26).bytes(message.member); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoPosRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoPosRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.member = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GeoPosRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + member: isSet(object.member) ? Buffer.from(bytesFromBase64(object.member)) : Buffer.alloc(0), + }; + }, + + toJSON(message: GeoPosRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.member.length !== 0) { + obj.member = base64FromBytes(message.member); + } + return obj; + }, + + create(base?: DeepPartial): GeoPosRequest { + return GeoPosRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GeoPosRequest { + const message = createBaseGeoPosRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.member = object.member ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseGeoPosResponse(): GeoPosResponse { + return { present: false, lon: 0, lat: 0 }; +} + +export const GeoPosResponse: MessageFns = { + encode(message: GeoPosResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + if (message.lon !== 0) { + writer.uint32(17).double(message.lon); + } + if (message.lat !== 0) { + writer.uint32(25).double(message.lat); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoPosResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoPosResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 17) { + break; + } + + message.lon = reader.double(); + continue; + } + case 3: { + if (tag !== 25) { + break; + } + + message.lat = reader.double(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GeoPosResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + lon: isSet(object.lon) ? globalThis.Number(object.lon) : 0, + lat: isSet(object.lat) ? globalThis.Number(object.lat) : 0, + }; + }, + + toJSON(message: GeoPosResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.lon !== 0) { + obj.lon = message.lon; + } + if (message.lat !== 0) { + obj.lat = message.lat; + } + return obj; + }, + + create(base?: DeepPartial): GeoPosResponse { + return GeoPosResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GeoPosResponse { + const message = createBaseGeoPosResponse(); + message.present = object.present ?? false; + message.lon = object.lon ?? 0; + message.lat = object.lat ?? 0; + return message; + }, +}; + +function createBaseGeoCardRequest(): GeoCardRequest { + return { keyspace: "", name: "" }; +} + +export const GeoCardRequest: MessageFns = { + encode(message: GeoCardRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoCardRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoCardRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GeoCardRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: GeoCardRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): GeoCardRequest { + return GeoCardRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GeoCardRequest { + const message = createBaseGeoCardRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseGeoCardResponse(): GeoCardResponse { + return { card: 0 }; +} + +export const GeoCardResponse: MessageFns = { + encode(message: GeoCardResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.card !== 0) { + writer.uint32(8).int64(message.card); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoCardResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoCardResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.card = longToNumber(reader.int64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GeoCardResponse { + return { card: isSet(object.card) ? globalThis.Number(object.card) : 0 }; + }, + + toJSON(message: GeoCardResponse): unknown { + const obj: any = {}; + if (message.card !== 0) { + obj.card = Math.round(message.card); + } + return obj; + }, + + create(base?: DeepPartial): GeoCardResponse { + return GeoCardResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GeoCardResponse { + const message = createBaseGeoCardResponse(); + message.card = object.card ?? 0; + return message; + }, +}; + +function createBaseGeoDistRequest(): GeoDistRequest { + return { keyspace: "", name: "", a: Buffer.alloc(0), b: Buffer.alloc(0) }; +} + +export const GeoDistRequest: MessageFns = { + encode(message: GeoDistRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.a.length !== 0) { + writer.uint32(26).bytes(message.a); + } + if (message.b.length !== 0) { + writer.uint32(34).bytes(message.b); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoDistRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoDistRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.a = Buffer.from(reader.bytes()); + continue; + } + case 4: { + if (tag !== 34) { + break; + } + + message.b = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GeoDistRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + a: isSet(object.a) ? Buffer.from(bytesFromBase64(object.a)) : Buffer.alloc(0), + b: isSet(object.b) ? Buffer.from(bytesFromBase64(object.b)) : Buffer.alloc(0), + }; + }, + + toJSON(message: GeoDistRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.a.length !== 0) { + obj.a = base64FromBytes(message.a); + } + if (message.b.length !== 0) { + obj.b = base64FromBytes(message.b); + } + return obj; + }, + + create(base?: DeepPartial): GeoDistRequest { + return GeoDistRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GeoDistRequest { + const message = createBaseGeoDistRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.a = object.a ?? Buffer.alloc(0); + message.b = object.b ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseGeoDistResponse(): GeoDistResponse { + return { present: false, meters: 0 }; +} + +export const GeoDistResponse: MessageFns = { + encode(message: GeoDistResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + if (message.meters !== 0) { + writer.uint32(17).double(message.meters); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoDistResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoDistResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 17) { + break; + } + + message.meters = reader.double(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GeoDistResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + meters: isSet(object.meters) ? globalThis.Number(object.meters) : 0, + }; + }, + + toJSON(message: GeoDistResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.meters !== 0) { + obj.meters = message.meters; + } + return obj; + }, + + create(base?: DeepPartial): GeoDistResponse { + return GeoDistResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GeoDistResponse { + const message = createBaseGeoDistResponse(); + message.present = object.present ?? false; + message.meters = object.meters ?? 0; + return message; + }, +}; + +function createBaseGeoRadiusRequest(): GeoRadiusRequest { + return { keyspace: "", name: "", lon: 0, lat: 0, radiusMeters: 0, limit: 0 }; +} + +export const GeoRadiusRequest: MessageFns = { + encode(message: GeoRadiusRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.lon !== 0) { + writer.uint32(25).double(message.lon); + } + if (message.lat !== 0) { + writer.uint32(33).double(message.lat); + } + if (message.radiusMeters !== 0) { + writer.uint32(41).double(message.radiusMeters); + } + if (message.limit !== 0) { + writer.uint32(48).int32(message.limit); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoRadiusRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoRadiusRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 25) { + break; + } + + message.lon = reader.double(); + continue; + } + case 4: { + if (tag !== 33) { + break; + } + + message.lat = reader.double(); + continue; + } + case 5: { + if (tag !== 41) { + break; + } + + message.radiusMeters = reader.double(); + continue; + } + case 6: { + if (tag !== 48) { + break; + } + + message.limit = reader.int32(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GeoRadiusRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + lon: isSet(object.lon) ? globalThis.Number(object.lon) : 0, + lat: isSet(object.lat) ? globalThis.Number(object.lat) : 0, + radiusMeters: isSet(object.radiusMeters) ? globalThis.Number(object.radiusMeters) : 0, + limit: isSet(object.limit) ? globalThis.Number(object.limit) : 0, + }; + }, + + toJSON(message: GeoRadiusRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.lon !== 0) { + obj.lon = message.lon; + } + if (message.lat !== 0) { + obj.lat = message.lat; + } + if (message.radiusMeters !== 0) { + obj.radiusMeters = message.radiusMeters; + } + if (message.limit !== 0) { + obj.limit = Math.round(message.limit); + } + return obj; + }, + + create(base?: DeepPartial): GeoRadiusRequest { + return GeoRadiusRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GeoRadiusRequest { + const message = createBaseGeoRadiusRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.lon = object.lon ?? 0; + message.lat = object.lat ?? 0; + message.radiusMeters = object.radiusMeters ?? 0; + message.limit = object.limit ?? 0; + return message; + }, +}; + +function createBaseGeoRadiusResponse(): GeoRadiusResponse { + return { members: [] }; +} + +export const GeoRadiusResponse: MessageFns = { + encode(message: GeoRadiusResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.members) { + GeoMember.encode(v!, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): GeoRadiusResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseGeoRadiusResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.members.push(GeoMember.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): GeoRadiusResponse { + return { + members: globalThis.Array.isArray(object?.members) ? object.members.map((e: any) => GeoMember.fromJSON(e)) : [], + }; + }, + + toJSON(message: GeoRadiusResponse): unknown { + const obj: any = {}; + if (message.members?.length) { + obj.members = message.members.map((e) => GeoMember.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): GeoRadiusResponse { + return GeoRadiusResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): GeoRadiusResponse { + const message = createBaseGeoRadiusResponse(); + message.members = object.members?.map((e) => GeoMember.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseLPushRequest(): LPushRequest { + return { keyspace: "", name: "", item: Buffer.alloc(0) }; +} + +export const LPushRequest: MessageFns = { + encode(message: LPushRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.item.length !== 0) { + writer.uint32(26).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LPushRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLPushRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): LPushRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: LPushRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): LPushRequest { + return LPushRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): LPushRequest { + const message = createBaseLPushRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseLPushResponse(): LPushResponse { + return {}; +} + +export const LPushResponse: MessageFns = { + encode(_: LPushResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LPushResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLPushResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): LPushResponse { + return {}; + }, + + toJSON(_: LPushResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): LPushResponse { + return LPushResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): LPushResponse { + const message = createBaseLPushResponse(); + return message; + }, +}; + +function createBaseRPushRequest(): RPushRequest { + return { keyspace: "", name: "", item: Buffer.alloc(0) }; +} + +export const RPushRequest: MessageFns = { + encode(message: RPushRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.item.length !== 0) { + writer.uint32(26).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): RPushRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRPushRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): RPushRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: RPushRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): RPushRequest { + return RPushRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): RPushRequest { + const message = createBaseRPushRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseRPushResponse(): RPushResponse { + return {}; +} + +export const RPushResponse: MessageFns = { + encode(_: RPushResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): RPushResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRPushResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): RPushResponse { + return {}; + }, + + toJSON(_: RPushResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): RPushResponse { + return RPushResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): RPushResponse { + const message = createBaseRPushResponse(); + return message; + }, +}; + +function createBaseLPopRequest(): LPopRequest { + return { keyspace: "", name: "" }; +} + +export const LPopRequest: MessageFns = { + encode(message: LPopRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LPopRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLPopRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): LPopRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: LPopRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): LPopRequest { + return LPopRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): LPopRequest { + const message = createBaseLPopRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseLPopResponse(): LPopResponse { + return { present: false, item: Buffer.alloc(0) }; +} + +export const LPopResponse: MessageFns = { + encode(message: LPopResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + if (message.item.length !== 0) { + writer.uint32(18).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LPopResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLPopResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): LPopResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: LPopResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): LPopResponse { + return LPopResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): LPopResponse { + const message = createBaseLPopResponse(); + message.present = object.present ?? false; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseRPopRequest(): RPopRequest { + return { keyspace: "", name: "" }; +} + +export const RPopRequest: MessageFns = { + encode(message: RPopRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): RPopRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRPopRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): RPopRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: RPopRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): RPopRequest { + return RPopRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): RPopRequest { + const message = createBaseRPopRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseRPopResponse(): RPopResponse { + return { present: false, item: Buffer.alloc(0) }; +} + +export const RPopResponse: MessageFns = { + encode(message: RPopResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + if (message.item.length !== 0) { + writer.uint32(18).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): RPopResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseRPopResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): RPopResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: RPopResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): RPopResponse { + return RPopResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): RPopResponse { + const message = createBaseRPopResponse(); + message.present = object.present ?? false; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseLLenRequest(): LLenRequest { + return { keyspace: "", name: "" }; +} + +export const LLenRequest: MessageFns = { + encode(message: LLenRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LLenRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLLenRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): LLenRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: LLenRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): LLenRequest { + return LLenRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): LLenRequest { + const message = createBaseLLenRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseLLenResponse(): LLenResponse { + return { len: 0 }; +} + +export const LLenResponse: MessageFns = { + encode(message: LLenResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.len !== 0) { + writer.uint32(8).int64(message.len); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LLenResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLLenResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.len = longToNumber(reader.int64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): LLenResponse { + return { len: isSet(object.len) ? globalThis.Number(object.len) : 0 }; + }, + + toJSON(message: LLenResponse): unknown { + const obj: any = {}; + if (message.len !== 0) { + obj.len = Math.round(message.len); + } + return obj; + }, + + create(base?: DeepPartial): LLenResponse { + return LLenResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): LLenResponse { + const message = createBaseLLenResponse(); + message.len = object.len ?? 0; + return message; + }, +}; + +function createBaseLIndexRequest(): LIndexRequest { + return { keyspace: "", name: "", index: 0 }; +} + +export const LIndexRequest: MessageFns = { + encode(message: LIndexRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.index !== 0) { + writer.uint32(24).int32(message.index); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LIndexRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLIndexRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.index = reader.int32(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): LIndexRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + index: isSet(object.index) ? globalThis.Number(object.index) : 0, + }; + }, + + toJSON(message: LIndexRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.index !== 0) { + obj.index = Math.round(message.index); + } + return obj; + }, + + create(base?: DeepPartial): LIndexRequest { + return LIndexRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): LIndexRequest { + const message = createBaseLIndexRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.index = object.index ?? 0; + return message; + }, +}; + +function createBaseLIndexResponse(): LIndexResponse { + return { present: false, item: Buffer.alloc(0) }; +} + +export const LIndexResponse: MessageFns = { + encode(message: LIndexResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + if (message.item.length !== 0) { + writer.uint32(18).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LIndexResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLIndexResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): LIndexResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: LIndexResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): LIndexResponse { + return LIndexResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): LIndexResponse { + const message = createBaseLIndexResponse(); + message.present = object.present ?? false; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseLRangeRequest(): LRangeRequest { + return { keyspace: "", name: "", start: 0, stop: 0 }; +} + +export const LRangeRequest: MessageFns = { + encode(message: LRangeRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.start !== 0) { + writer.uint32(24).int32(message.start); + } + if (message.stop !== 0) { + writer.uint32(32).int32(message.stop); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LRangeRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLRangeRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.start = reader.int32(); + continue; + } + case 4: { + if (tag !== 32) { + break; + } + + message.stop = reader.int32(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): LRangeRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + start: isSet(object.start) ? globalThis.Number(object.start) : 0, + stop: isSet(object.stop) ? globalThis.Number(object.stop) : 0, + }; + }, + + toJSON(message: LRangeRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.start !== 0) { + obj.start = Math.round(message.start); + } + if (message.stop !== 0) { + obj.stop = Math.round(message.stop); + } + return obj; + }, + + create(base?: DeepPartial): LRangeRequest { + return LRangeRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): LRangeRequest { + const message = createBaseLRangeRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.start = object.start ?? 0; + message.stop = object.stop ?? 0; + return message; + }, +}; + +function createBaseLRangeResponse(): LRangeResponse { + return { items: [] }; +} + +export const LRangeResponse: MessageFns = { + encode(message: LRangeResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.items) { + writer.uint32(10).bytes(v!); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): LRangeResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLRangeResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.items.push(Buffer.from(reader.bytes())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): LRangeResponse { + return { + items: globalThis.Array.isArray(object?.items) + ? object.items.map((e: any) => Buffer.from(bytesFromBase64(e))) + : [], + }; + }, + + toJSON(message: LRangeResponse): unknown { + const obj: any = {}; + if (message.items?.length) { + obj.items = message.items.map((e) => base64FromBytes(e)); + } + return obj; + }, + + create(base?: DeepPartial): LRangeResponse { + return LRangeResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): LRangeResponse { + const message = createBaseLRangeResponse(); + message.items = object.items?.map((e) => e) || []; + return message; + }, +}; + +function createBaseHSetRequest(): HSetRequest { + return { keyspace: "", name: "", field: Buffer.alloc(0), value: Buffer.alloc(0) }; +} + +export const HSetRequest: MessageFns = { + encode(message: HSetRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.field.length !== 0) { + writer.uint32(26).bytes(message.field); + } + if (message.value.length !== 0) { + writer.uint32(34).bytes(message.value); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HSetRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHSetRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.field = Buffer.from(reader.bytes()); + continue; + } + case 4: { + if (tag !== 34) { + break; + } + + message.value = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HSetRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + field: isSet(object.field) ? Buffer.from(bytesFromBase64(object.field)) : Buffer.alloc(0), + value: isSet(object.value) ? Buffer.from(bytesFromBase64(object.value)) : Buffer.alloc(0), + }; + }, + + toJSON(message: HSetRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.field.length !== 0) { + obj.field = base64FromBytes(message.field); + } + if (message.value.length !== 0) { + obj.value = base64FromBytes(message.value); + } + return obj; + }, + + create(base?: DeepPartial): HSetRequest { + return HSetRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HSetRequest { + const message = createBaseHSetRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.field = object.field ?? Buffer.alloc(0); + message.value = object.value ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseHSetResponse(): HSetResponse { + return {}; +} + +export const HSetResponse: MessageFns = { + encode(_: HSetResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HSetResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHSetResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): HSetResponse { + return {}; + }, + + toJSON(_: HSetResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): HSetResponse { + return HSetResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): HSetResponse { + const message = createBaseHSetResponse(); + return message; + }, +}; + +function createBaseHGetRequest(): HGetRequest { + return { keyspace: "", name: "", field: Buffer.alloc(0) }; +} + +export const HGetRequest: MessageFns = { + encode(message: HGetRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.field.length !== 0) { + writer.uint32(26).bytes(message.field); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HGetRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHGetRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.field = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HGetRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + field: isSet(object.field) ? Buffer.from(bytesFromBase64(object.field)) : Buffer.alloc(0), + }; + }, + + toJSON(message: HGetRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.field.length !== 0) { + obj.field = base64FromBytes(message.field); + } + return obj; + }, + + create(base?: DeepPartial): HGetRequest { + return HGetRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HGetRequest { + const message = createBaseHGetRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.field = object.field ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseHGetResponse(): HGetResponse { + return { present: false, value: Buffer.alloc(0) }; +} + +export const HGetResponse: MessageFns = { + encode(message: HGetResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + if (message.value.length !== 0) { + writer.uint32(18).bytes(message.value); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HGetResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHGetResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.value = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HGetResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + value: isSet(object.value) ? Buffer.from(bytesFromBase64(object.value)) : Buffer.alloc(0), + }; + }, + + toJSON(message: HGetResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.value.length !== 0) { + obj.value = base64FromBytes(message.value); + } + return obj; + }, + + create(base?: DeepPartial): HGetResponse { + return HGetResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HGetResponse { + const message = createBaseHGetResponse(); + message.present = object.present ?? false; + message.value = object.value ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseHDelRequest(): HDelRequest { + return { keyspace: "", name: "", field: Buffer.alloc(0) }; +} + +export const HDelRequest: MessageFns = { + encode(message: HDelRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.field.length !== 0) { + writer.uint32(26).bytes(message.field); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HDelRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHDelRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.field = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HDelRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + field: isSet(object.field) ? Buffer.from(bytesFromBase64(object.field)) : Buffer.alloc(0), + }; + }, + + toJSON(message: HDelRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.field.length !== 0) { + obj.field = base64FromBytes(message.field); + } + return obj; + }, + + create(base?: DeepPartial): HDelRequest { + return HDelRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HDelRequest { + const message = createBaseHDelRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.field = object.field ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseHDelResponse(): HDelResponse { + return {}; +} + +export const HDelResponse: MessageFns = { + encode(_: HDelResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HDelResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHDelResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): HDelResponse { + return {}; + }, + + toJSON(_: HDelResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): HDelResponse { + return HDelResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): HDelResponse { + const message = createBaseHDelResponse(); + return message; + }, +}; + +function createBaseHExistsRequest(): HExistsRequest { + return { keyspace: "", name: "", field: Buffer.alloc(0) }; +} + +export const HExistsRequest: MessageFns = { + encode(message: HExistsRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.field.length !== 0) { + writer.uint32(26).bytes(message.field); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HExistsRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHExistsRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.field = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HExistsRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + field: isSet(object.field) ? Buffer.from(bytesFromBase64(object.field)) : Buffer.alloc(0), + }; + }, + + toJSON(message: HExistsRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.field.length !== 0) { + obj.field = base64FromBytes(message.field); + } + return obj; + }, + + create(base?: DeepPartial): HExistsRequest { + return HExistsRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HExistsRequest { + const message = createBaseHExistsRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.field = object.field ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseHExistsResponse(): HExistsResponse { + return { present: false }; +} + +export const HExistsResponse: MessageFns = { + encode(message: HExistsResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HExistsResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHExistsResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HExistsResponse { + return { present: isSet(object.present) ? globalThis.Boolean(object.present) : false }; + }, + + toJSON(message: HExistsResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + return obj; + }, + + create(base?: DeepPartial): HExistsResponse { + return HExistsResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HExistsResponse { + const message = createBaseHExistsResponse(); + message.present = object.present ?? false; + return message; + }, +}; + +function createBaseHLenRequest(): HLenRequest { + return { keyspace: "", name: "" }; +} + +export const HLenRequest: MessageFns = { + encode(message: HLenRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HLenRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHLenRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HLenRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: HLenRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): HLenRequest { + return HLenRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HLenRequest { + const message = createBaseHLenRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseHLenResponse(): HLenResponse { + return { len: 0 }; +} + +export const HLenResponse: MessageFns = { + encode(message: HLenResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.len !== 0) { + writer.uint32(8).int64(message.len); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HLenResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHLenResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.len = longToNumber(reader.int64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HLenResponse { + return { len: isSet(object.len) ? globalThis.Number(object.len) : 0 }; + }, + + toJSON(message: HLenResponse): unknown { + const obj: any = {}; + if (message.len !== 0) { + obj.len = Math.round(message.len); + } + return obj; + }, + + create(base?: DeepPartial): HLenResponse { + return HLenResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HLenResponse { + const message = createBaseHLenResponse(); + message.len = object.len ?? 0; + return message; + }, +}; + +function createBaseHGetAllRequest(): HGetAllRequest { + return { keyspace: "", name: "" }; +} + +export const HGetAllRequest: MessageFns = { + encode(message: HGetAllRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HGetAllRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHGetAllRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HGetAllRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: HGetAllRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): HGetAllRequest { + return HGetAllRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HGetAllRequest { + const message = createBaseHGetAllRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseHashField(): HashField { + return { field: Buffer.alloc(0), value: Buffer.alloc(0) }; +} + +export const HashField: MessageFns = { + encode(message: HashField, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.field.length !== 0) { + writer.uint32(10).bytes(message.field); + } + if (message.value.length !== 0) { + writer.uint32(18).bytes(message.value); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HashField { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHashField(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.field = Buffer.from(reader.bytes()); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.value = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HashField { + return { + field: isSet(object.field) ? Buffer.from(bytesFromBase64(object.field)) : Buffer.alloc(0), + value: isSet(object.value) ? Buffer.from(bytesFromBase64(object.value)) : Buffer.alloc(0), + }; + }, + + toJSON(message: HashField): unknown { + const obj: any = {}; + if (message.field.length !== 0) { + obj.field = base64FromBytes(message.field); + } + if (message.value.length !== 0) { + obj.value = base64FromBytes(message.value); + } + return obj; + }, + + create(base?: DeepPartial): HashField { + return HashField.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HashField { + const message = createBaseHashField(); + message.field = object.field ?? Buffer.alloc(0); + message.value = object.value ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseHGetAllResponse(): HGetAllResponse { + return { fields: [] }; +} + +export const HGetAllResponse: MessageFns = { + encode(message: HGetAllResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.fields) { + HashField.encode(v!, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HGetAllResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHGetAllResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.fields.push(HashField.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HGetAllResponse { + return { + fields: globalThis.Array.isArray(object?.fields) ? object.fields.map((e: any) => HashField.fromJSON(e)) : [], + }; + }, + + toJSON(message: HGetAllResponse): unknown { + const obj: any = {}; + if (message.fields?.length) { + obj.fields = message.fields.map((e) => HashField.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): HGetAllResponse { + return HGetAllResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HGetAllResponse { + const message = createBaseHGetAllResponse(); + message.fields = object.fields?.map((e) => HashField.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseIncrRequest(): IncrRequest { + return { keyspace: "", name: "", delta: 0 }; +} + +export const IncrRequest: MessageFns = { + encode(message: IncrRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.delta !== 0) { + writer.uint32(24).int64(message.delta); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): IncrRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseIncrRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.delta = longToNumber(reader.int64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): IncrRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + delta: isSet(object.delta) ? globalThis.Number(object.delta) : 0, + }; + }, + + toJSON(message: IncrRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.delta !== 0) { + obj.delta = Math.round(message.delta); + } + return obj; + }, + + create(base?: DeepPartial): IncrRequest { + return IncrRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): IncrRequest { + const message = createBaseIncrRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.delta = object.delta ?? 0; + return message; + }, +}; + +function createBaseIncrResponse(): IncrResponse { + return { value: 0 }; +} + +export const IncrResponse: MessageFns = { + encode(message: IncrResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.value !== 0) { + writer.uint32(8).int64(message.value); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): IncrResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseIncrResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.value = longToNumber(reader.int64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): IncrResponse { + return { value: isSet(object.value) ? globalThis.Number(object.value) : 0 }; + }, + + toJSON(message: IncrResponse): unknown { + const obj: any = {}; + if (message.value !== 0) { + obj.value = Math.round(message.value); + } + return obj; + }, + + create(base?: DeepPartial): IncrResponse { + return IncrResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): IncrResponse { + const message = createBaseIncrResponse(); + message.value = object.value ?? 0; + return message; + }, +}; + +function createBaseCounterGetRequest(): CounterGetRequest { + return { keyspace: "", name: "" }; +} + +export const CounterGetRequest: MessageFns = { + encode(message: CounterGetRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): CounterGetRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseCounterGetRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): CounterGetRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: CounterGetRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): CounterGetRequest { + return CounterGetRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): CounterGetRequest { + const message = createBaseCounterGetRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseCounterGetResponse(): CounterGetResponse { + return { present: false, value: 0 }; +} + +export const CounterGetResponse: MessageFns = { + encode(message: CounterGetResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + if (message.value !== 0) { + writer.uint32(16).int64(message.value); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): CounterGetResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseCounterGetResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 16) { + break; + } + + message.value = longToNumber(reader.int64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): CounterGetResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + value: isSet(object.value) ? globalThis.Number(object.value) : 0, + }; + }, + + toJSON(message: CounterGetResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.value !== 0) { + obj.value = Math.round(message.value); + } + return obj; + }, + + create(base?: DeepPartial): CounterGetResponse { + return CounterGetResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): CounterGetResponse { + const message = createBaseCounterGetResponse(); + message.present = object.present ?? false; + message.value = object.value ?? 0; + return message; + }, +}; + +function createBaseJsonSetRequest(): JsonSetRequest { + return { keyspace: "", name: "", path: "", value: Buffer.alloc(0) }; +} + +export const JsonSetRequest: MessageFns = { + encode(message: JsonSetRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.path !== "") { + writer.uint32(26).string(message.path); + } + if (message.value.length !== 0) { + writer.uint32(34).bytes(message.value); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): JsonSetRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseJsonSetRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.path = reader.string(); + continue; + } + case 4: { + if (tag !== 34) { + break; + } + + message.value = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): JsonSetRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + path: isSet(object.path) ? globalThis.String(object.path) : "", + value: isSet(object.value) ? Buffer.from(bytesFromBase64(object.value)) : Buffer.alloc(0), + }; + }, + + toJSON(message: JsonSetRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.path !== "") { + obj.path = message.path; + } + if (message.value.length !== 0) { + obj.value = base64FromBytes(message.value); + } + return obj; + }, + + create(base?: DeepPartial): JsonSetRequest { + return JsonSetRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): JsonSetRequest { + const message = createBaseJsonSetRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.path = object.path ?? ""; + message.value = object.value ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseJsonSetResponse(): JsonSetResponse { + return {}; +} + +export const JsonSetResponse: MessageFns = { + encode(_: JsonSetResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): JsonSetResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseJsonSetResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): JsonSetResponse { + return {}; + }, + + toJSON(_: JsonSetResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): JsonSetResponse { + return JsonSetResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): JsonSetResponse { + const message = createBaseJsonSetResponse(); + return message; + }, +}; + +function createBaseJsonGetRequest(): JsonGetRequest { + return { keyspace: "", name: "", path: "" }; +} + +export const JsonGetRequest: MessageFns = { + encode(message: JsonGetRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.path !== "") { + writer.uint32(26).string(message.path); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): JsonGetRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseJsonGetRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.path = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): JsonGetRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + path: isSet(object.path) ? globalThis.String(object.path) : "", + }; + }, + + toJSON(message: JsonGetRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.path !== "") { + obj.path = message.path; + } + return obj; + }, + + create(base?: DeepPartial): JsonGetRequest { + return JsonGetRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): JsonGetRequest { + const message = createBaseJsonGetRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.path = object.path ?? ""; + return message; + }, +}; + +function createBaseJsonGetResponse(): JsonGetResponse { + return { present: false, value: Buffer.alloc(0) }; +} + +export const JsonGetResponse: MessageFns = { + encode(message: JsonGetResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + if (message.value.length !== 0) { + writer.uint32(18).bytes(message.value); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): JsonGetResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseJsonGetResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.value = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): JsonGetResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + value: isSet(object.value) ? Buffer.from(bytesFromBase64(object.value)) : Buffer.alloc(0), + }; + }, + + toJSON(message: JsonGetResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.value.length !== 0) { + obj.value = base64FromBytes(message.value); + } + return obj; + }, + + create(base?: DeepPartial): JsonGetResponse { + return JsonGetResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): JsonGetResponse { + const message = createBaseJsonGetResponse(); + message.present = object.present ?? false; + message.value = object.value ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseJsonDelRequest(): JsonDelRequest { + return { keyspace: "", name: "", path: "" }; +} + +export const JsonDelRequest: MessageFns = { + encode(message: JsonDelRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.path !== "") { + writer.uint32(26).string(message.path); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): JsonDelRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseJsonDelRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.path = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): JsonDelRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + path: isSet(object.path) ? globalThis.String(object.path) : "", + }; + }, + + toJSON(message: JsonDelRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.path !== "") { + obj.path = message.path; + } + return obj; + }, + + create(base?: DeepPartial): JsonDelRequest { + return JsonDelRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): JsonDelRequest { + const message = createBaseJsonDelRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.path = object.path ?? ""; + return message; + }, +}; + +function createBaseJsonDelResponse(): JsonDelResponse { + return {}; +} + +export const JsonDelResponse: MessageFns = { + encode(_: JsonDelResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): JsonDelResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseJsonDelResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): JsonDelResponse { + return {}; + }, + + toJSON(_: JsonDelResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): JsonDelResponse { + return JsonDelResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): JsonDelResponse { + const message = createBaseJsonDelResponse(); + return message; + }, +}; + +function createBaseBitSetRequest(): BitSetRequest { + return { keyspace: "", name: "", offset: 0, bit: false }; +} + +export const BitSetRequest: MessageFns = { + encode(message: BitSetRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.offset !== 0) { + writer.uint32(24).uint64(message.offset); + } + if (message.bit !== false) { + writer.uint32(32).bool(message.bit); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): BitSetRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBitSetRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.offset = longToNumber(reader.uint64()); + continue; + } + case 4: { + if (tag !== 32) { + break; + } + + message.bit = reader.bool(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): BitSetRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + offset: isSet(object.offset) ? globalThis.Number(object.offset) : 0, + bit: isSet(object.bit) ? globalThis.Boolean(object.bit) : false, + }; + }, + + toJSON(message: BitSetRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.offset !== 0) { + obj.offset = Math.round(message.offset); + } + if (message.bit !== false) { + obj.bit = message.bit; + } + return obj; + }, + + create(base?: DeepPartial): BitSetRequest { + return BitSetRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): BitSetRequest { + const message = createBaseBitSetRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.offset = object.offset ?? 0; + message.bit = object.bit ?? false; + return message; + }, +}; + +function createBaseBitSetResponse(): BitSetResponse { + return {}; +} + +export const BitSetResponse: MessageFns = { + encode(_: BitSetResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): BitSetResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBitSetResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): BitSetResponse { + return {}; + }, + + toJSON(_: BitSetResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): BitSetResponse { + return BitSetResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): BitSetResponse { + const message = createBaseBitSetResponse(); + return message; + }, +}; + +function createBaseBitGetRequest(): BitGetRequest { + return { keyspace: "", name: "", offset: 0 }; +} + +export const BitGetRequest: MessageFns = { + encode(message: BitGetRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.offset !== 0) { + writer.uint32(24).uint64(message.offset); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): BitGetRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBitGetRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.offset = longToNumber(reader.uint64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): BitGetRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + offset: isSet(object.offset) ? globalThis.Number(object.offset) : 0, + }; + }, + + toJSON(message: BitGetRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.offset !== 0) { + obj.offset = Math.round(message.offset); + } + return obj; + }, + + create(base?: DeepPartial): BitGetRequest { + return BitGetRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): BitGetRequest { + const message = createBaseBitGetRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.offset = object.offset ?? 0; + return message; + }, +}; + +function createBaseBitGetResponse(): BitGetResponse { + return { present: false, bit: false }; +} + +export const BitGetResponse: MessageFns = { + encode(message: BitGetResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + if (message.bit !== false) { + writer.uint32(16).bool(message.bit); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): BitGetResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBitGetResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 16) { + break; + } + + message.bit = reader.bool(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): BitGetResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + bit: isSet(object.bit) ? globalThis.Boolean(object.bit) : false, + }; + }, + + toJSON(message: BitGetResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.bit !== false) { + obj.bit = message.bit; + } + return obj; + }, + + create(base?: DeepPartial): BitGetResponse { + return BitGetResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): BitGetResponse { + const message = createBaseBitGetResponse(); + message.present = object.present ?? false; + message.bit = object.bit ?? false; + return message; + }, +}; + +function createBaseBitCountRequest(): BitCountRequest { + return { keyspace: "", name: "", start: 0, end: 0 }; +} + +export const BitCountRequest: MessageFns = { + encode(message: BitCountRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.start !== 0) { + writer.uint32(24).int32(message.start); + } + if (message.end !== 0) { + writer.uint32(32).int32(message.end); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): BitCountRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBitCountRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.start = reader.int32(); + continue; + } + case 4: { + if (tag !== 32) { + break; + } + + message.end = reader.int32(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): BitCountRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + start: isSet(object.start) ? globalThis.Number(object.start) : 0, + end: isSet(object.end) ? globalThis.Number(object.end) : 0, + }; + }, + + toJSON(message: BitCountRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.start !== 0) { + obj.start = Math.round(message.start); + } + if (message.end !== 0) { + obj.end = Math.round(message.end); + } + return obj; + }, + + create(base?: DeepPartial): BitCountRequest { + return BitCountRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): BitCountRequest { + const message = createBaseBitCountRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.start = object.start ?? 0; + message.end = object.end ?? 0; + return message; + }, +}; + +function createBaseBitCountResponse(): BitCountResponse { + return { count: 0 }; +} + +export const BitCountResponse: MessageFns = { + encode(message: BitCountResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.count !== 0) { + writer.uint32(8).int64(message.count); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): BitCountResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBitCountResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.count = longToNumber(reader.int64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): BitCountResponse { + return { count: isSet(object.count) ? globalThis.Number(object.count) : 0 }; + }, + + toJSON(message: BitCountResponse): unknown { + const obj: any = {}; + if (message.count !== 0) { + obj.count = Math.round(message.count); + } + return obj; + }, + + create(base?: DeepPartial): BitCountResponse { + return BitCountResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): BitCountResponse { + const message = createBaseBitCountResponse(); + message.count = object.count ?? 0; + return message; + }, +}; + +function createBaseBitPosRequest(): BitPosRequest { + return { keyspace: "", name: "", bit: false, start: 0, end: 0 }; +} + +export const BitPosRequest: MessageFns = { + encode(message: BitPosRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.bit !== false) { + writer.uint32(24).bool(message.bit); + } + if (message.start !== 0) { + writer.uint32(32).int32(message.start); + } + if (message.end !== 0) { + writer.uint32(40).int32(message.end); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): BitPosRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBitPosRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.bit = reader.bool(); + continue; + } + case 4: { + if (tag !== 32) { + break; + } + + message.start = reader.int32(); + continue; + } + case 5: { + if (tag !== 40) { + break; + } + + message.end = reader.int32(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): BitPosRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + bit: isSet(object.bit) ? globalThis.Boolean(object.bit) : false, + start: isSet(object.start) ? globalThis.Number(object.start) : 0, + end: isSet(object.end) ? globalThis.Number(object.end) : 0, + }; + }, + + toJSON(message: BitPosRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.bit !== false) { + obj.bit = message.bit; + } + if (message.start !== 0) { + obj.start = Math.round(message.start); + } + if (message.end !== 0) { + obj.end = Math.round(message.end); + } + return obj; + }, + + create(base?: DeepPartial): BitPosRequest { + return BitPosRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): BitPosRequest { + const message = createBaseBitPosRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.bit = object.bit ?? false; + message.start = object.start ?? 0; + message.end = object.end ?? 0; + return message; + }, +}; + +function createBaseBitPosResponse(): BitPosResponse { + return { found: false, pos: 0 }; +} + +export const BitPosResponse: MessageFns = { + encode(message: BitPosResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.found !== false) { + writer.uint32(8).bool(message.found); + } + if (message.pos !== 0) { + writer.uint32(16).int64(message.pos); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): BitPosResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseBitPosResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.found = reader.bool(); + continue; + } + case 2: { + if (tag !== 16) { + break; + } + + message.pos = longToNumber(reader.int64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): BitPosResponse { + return { + found: isSet(object.found) ? globalThis.Boolean(object.found) : false, + pos: isSet(object.pos) ? globalThis.Number(object.pos) : 0, + }; + }, + + toJSON(message: BitPosResponse): unknown { + const obj: any = {}; + if (message.found !== false) { + obj.found = message.found; + } + if (message.pos !== 0) { + obj.pos = Math.round(message.pos); + } + return obj; + }, + + create(base?: DeepPartial): BitPosResponse { + return BitPosResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): BitPosResponse { + const message = createBaseBitPosResponse(); + message.found = object.found ?? false; + message.pos = object.pos ?? 0; + return message; + }, +}; + +function createBaseHLLAddRequest(): HLLAddRequest { + return { keyspace: "", name: "", item: Buffer.alloc(0) }; +} + +export const HLLAddRequest: MessageFns = { + encode(message: HLLAddRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.item.length !== 0) { + writer.uint32(26).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HLLAddRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHLLAddRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HLLAddRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: HLLAddRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): HLLAddRequest { + return HLLAddRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HLLAddRequest { + const message = createBaseHLLAddRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseHLLAddResponse(): HLLAddResponse { + return {}; +} + +export const HLLAddResponse: MessageFns = { + encode(_: HLLAddResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HLLAddResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHLLAddResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): HLLAddResponse { + return {}; + }, + + toJSON(_: HLLAddResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): HLLAddResponse { + return HLLAddResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): HLLAddResponse { + const message = createBaseHLLAddResponse(); + return message; + }, +}; + +function createBaseHLLCountRequest(): HLLCountRequest { + return { keyspace: "", name: "" }; +} + +export const HLLCountRequest: MessageFns = { + encode(message: HLLCountRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HLLCountRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHLLCountRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HLLCountRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: HLLCountRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): HLLCountRequest { + return HLLCountRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HLLCountRequest { + const message = createBaseHLLCountRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseHLLCountResponse(): HLLCountResponse { + return { present: false, count: 0 }; +} + +export const HLLCountResponse: MessageFns = { + encode(message: HLLCountResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + if (message.count !== 0) { + writer.uint32(16).uint64(message.count); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): HLLCountResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseHLLCountResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 16) { + break; + } + + message.count = longToNumber(reader.uint64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): HLLCountResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + count: isSet(object.count) ? globalThis.Number(object.count) : 0, + }; + }, + + toJSON(message: HLLCountResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.count !== 0) { + obj.count = Math.round(message.count); + } + return obj; + }, + + create(base?: DeepPartial): HLLCountResponse { + return HLLCountResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): HLLCountResponse { + const message = createBaseHLLCountResponse(); + message.present = object.present ?? false; + message.count = object.count ?? 0; + return message; + }, +}; + +function createBaseTopKAddRequest(): TopKAddRequest { + return { keyspace: "", name: "", item: Buffer.alloc(0) }; +} + +export const TopKAddRequest: MessageFns = { + encode(message: TopKAddRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.item.length !== 0) { + writer.uint32(26).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): TopKAddRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseTopKAddRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): TopKAddRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: TopKAddRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): TopKAddRequest { + return TopKAddRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): TopKAddRequest { + const message = createBaseTopKAddRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseTopKAddResponse(): TopKAddResponse { + return {}; +} + +export const TopKAddResponse: MessageFns = { + encode(_: TopKAddResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): TopKAddResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseTopKAddResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): TopKAddResponse { + return {}; + }, + + toJSON(_: TopKAddResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): TopKAddResponse { + return TopKAddResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): TopKAddResponse { + const message = createBaseTopKAddResponse(); + return message; + }, +}; + +function createBaseTopKListRequest(): TopKListRequest { + return { keyspace: "", name: "" }; +} + +export const TopKListRequest: MessageFns = { + encode(message: TopKListRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): TopKListRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseTopKListRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): TopKListRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: TopKListRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): TopKListRequest { + return TopKListRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): TopKListRequest { + const message = createBaseTopKListRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseTopKEntry(): TopKEntry { + return { item: Buffer.alloc(0), count: 0 }; +} + +export const TopKEntry: MessageFns = { + encode(message: TopKEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.item.length !== 0) { + writer.uint32(10).bytes(message.item); + } + if (message.count !== 0) { + writer.uint32(16).uint64(message.count); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): TopKEntry { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseTopKEntry(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + case 2: { + if (tag !== 16) { + break; + } + + message.count = longToNumber(reader.uint64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): TopKEntry { + return { + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + count: isSet(object.count) ? globalThis.Number(object.count) : 0, + }; + }, + + toJSON(message: TopKEntry): unknown { + const obj: any = {}; + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + if (message.count !== 0) { + obj.count = Math.round(message.count); + } + return obj; + }, + + create(base?: DeepPartial): TopKEntry { + return TopKEntry.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): TopKEntry { + const message = createBaseTopKEntry(); + message.item = object.item ?? Buffer.alloc(0); + message.count = object.count ?? 0; + return message; + }, +}; + +function createBaseTopKListResponse(): TopKListResponse { + return { present: false, entries: [] }; +} + +export const TopKListResponse: MessageFns = { + encode(message: TopKListResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + for (const v of message.entries) { + TopKEntry.encode(v!, writer.uint32(18).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): TopKListResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseTopKListResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.entries.push(TopKEntry.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): TopKListResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + entries: globalThis.Array.isArray(object?.entries) ? object.entries.map((e: any) => TopKEntry.fromJSON(e)) : [], + }; + }, + + toJSON(message: TopKListResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.entries?.length) { + obj.entries = message.entries.map((e) => TopKEntry.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): TopKListResponse { + return TopKListResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): TopKListResponse { + const message = createBaseTopKListResponse(); + message.present = object.present ?? false; + message.entries = object.entries?.map((e) => TopKEntry.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseCMSIncrRequest(): CMSIncrRequest { + return { keyspace: "", name: "", item: Buffer.alloc(0), n: 0 }; +} + +export const CMSIncrRequest: MessageFns = { + encode(message: CMSIncrRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.item.length !== 0) { + writer.uint32(26).bytes(message.item); + } + if (message.n !== 0) { + writer.uint32(32).uint64(message.n); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): CMSIncrRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseCMSIncrRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + case 4: { + if (tag !== 32) { + break; + } + + message.n = longToNumber(reader.uint64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): CMSIncrRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + n: isSet(object.n) ? globalThis.Number(object.n) : 0, + }; + }, + + toJSON(message: CMSIncrRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + if (message.n !== 0) { + obj.n = Math.round(message.n); + } + return obj; + }, + + create(base?: DeepPartial): CMSIncrRequest { + return CMSIncrRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): CMSIncrRequest { + const message = createBaseCMSIncrRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.item = object.item ?? Buffer.alloc(0); + message.n = object.n ?? 0; + return message; + }, +}; + +function createBaseCMSIncrResponse(): CMSIncrResponse { + return {}; +} + +export const CMSIncrResponse: MessageFns = { + encode(_: CMSIncrResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): CMSIncrResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseCMSIncrResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): CMSIncrResponse { + return {}; + }, + + toJSON(_: CMSIncrResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): CMSIncrResponse { + return CMSIncrResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): CMSIncrResponse { + const message = createBaseCMSIncrResponse(); + return message; + }, +}; + +function createBaseCMSQueryRequest(): CMSQueryRequest { + return { keyspace: "", name: "", item: Buffer.alloc(0) }; +} + +export const CMSQueryRequest: MessageFns = { + encode(message: CMSQueryRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.item.length !== 0) { + writer.uint32(26).bytes(message.item); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): CMSQueryRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseCMSQueryRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.item = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): CMSQueryRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + item: isSet(object.item) ? Buffer.from(bytesFromBase64(object.item)) : Buffer.alloc(0), + }; + }, + + toJSON(message: CMSQueryRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.item.length !== 0) { + obj.item = base64FromBytes(message.item); + } + return obj; + }, + + create(base?: DeepPartial): CMSQueryRequest { + return CMSQueryRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): CMSQueryRequest { + const message = createBaseCMSQueryRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.item = object.item ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseCMSQueryResponse(): CMSQueryResponse { + return { present: false, count: 0 }; +} + +export const CMSQueryResponse: MessageFns = { + encode(message: CMSQueryResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.present !== false) { + writer.uint32(8).bool(message.present); + } + if (message.count !== 0) { + writer.uint32(16).uint64(message.count); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): CMSQueryResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseCMSQueryResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.present = reader.bool(); + continue; + } + case 2: { + if (tag !== 16) { + break; + } + + message.count = longToNumber(reader.uint64()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): CMSQueryResponse { + return { + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + count: isSet(object.count) ? globalThis.Number(object.count) : 0, + }; + }, + + toJSON(message: CMSQueryResponse): unknown { + const obj: any = {}; + if (message.present !== false) { + obj.present = message.present; + } + if (message.count !== 0) { + obj.count = Math.round(message.count); + } + return obj; + }, + + create(base?: DeepPartial): CMSQueryResponse { + return CMSQueryResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): CMSQueryResponse { + const message = createBaseCMSQueryResponse(); + message.present = object.present ?? false; + message.count = object.count ?? 0; + return message; + }, +}; + +function createBaseVAddRequest(): VAddRequest { + return { keyspace: "", name: "", member: Buffer.alloc(0), vec: [] }; +} + +export const VAddRequest: MessageFns = { + encode(message: VAddRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.member.length !== 0) { + writer.uint32(26).bytes(message.member); + } + writer.uint32(34).fork(); + for (const v of message.vec) { + writer.float(v); + } + writer.join(); + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VAddRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVAddRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.member = Buffer.from(reader.bytes()); + continue; + } + case 4: { + if (tag === 37) { + message.vec.push(reader.float()); + + continue; + } + + if (tag === 34) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.vec.push(reader.float()); + } + + continue; + } + + break; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VAddRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + member: isSet(object.member) ? Buffer.from(bytesFromBase64(object.member)) : Buffer.alloc(0), + vec: globalThis.Array.isArray(object?.vec) ? object.vec.map((e: any) => globalThis.Number(e)) : [], + }; + }, + + toJSON(message: VAddRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.member.length !== 0) { + obj.member = base64FromBytes(message.member); + } + if (message.vec?.length) { + obj.vec = message.vec; + } + return obj; + }, + + create(base?: DeepPartial): VAddRequest { + return VAddRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): VAddRequest { + const message = createBaseVAddRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.member = object.member ?? Buffer.alloc(0); + message.vec = object.vec?.map((e) => e) || []; + return message; + }, +}; + +function createBaseVAddResponse(): VAddResponse { + return {}; +} + +export const VAddResponse: MessageFns = { + encode(_: VAddResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VAddResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVAddResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): VAddResponse { + return {}; + }, + + toJSON(_: VAddResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): VAddResponse { + return VAddResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): VAddResponse { + const message = createBaseVAddResponse(); + return message; + }, +}; + +function createBaseVRemRequest(): VRemRequest { + return { keyspace: "", name: "", member: Buffer.alloc(0) }; +} + +export const VRemRequest: MessageFns = { + encode(message: VRemRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.member.length !== 0) { + writer.uint32(26).bytes(message.member); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VRemRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVRemRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.member = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VRemRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + member: isSet(object.member) ? Buffer.from(bytesFromBase64(object.member)) : Buffer.alloc(0), + }; + }, + + toJSON(message: VRemRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.member.length !== 0) { + obj.member = base64FromBytes(message.member); + } + return obj; + }, + + create(base?: DeepPartial): VRemRequest { + return VRemRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): VRemRequest { + const message = createBaseVRemRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.member = object.member ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseVRemResponse(): VRemResponse { + return {}; +} + +export const VRemResponse: MessageFns = { + encode(_: VRemResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VRemResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVRemResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): VRemResponse { + return {}; + }, + + toJSON(_: VRemResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): VRemResponse { + return VRemResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): VRemResponse { + const message = createBaseVRemResponse(); + return message; + }, +}; + +function createBaseVSimRequest(): VSimRequest { + return { keyspace: "", name: "", vec: [], k: 0 }; +} + +export const VSimRequest: MessageFns = { + encode(message: VSimRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + writer.uint32(26).fork(); + for (const v of message.vec) { + writer.float(v); + } + writer.join(); + if (message.k !== 0) { + writer.uint32(32).int32(message.k); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VSimRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVSimRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag === 29) { + message.vec.push(reader.float()); + + continue; + } + + if (tag === 26) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.vec.push(reader.float()); + } + + continue; + } + + break; + } + case 4: { + if (tag !== 32) { + break; + } + + message.k = reader.int32(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VSimRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + vec: globalThis.Array.isArray(object?.vec) ? object.vec.map((e: any) => globalThis.Number(e)) : [], + k: isSet(object.k) ? globalThis.Number(object.k) : 0, + }; + }, + + toJSON(message: VSimRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.vec?.length) { + obj.vec = message.vec; + } + if (message.k !== 0) { + obj.k = Math.round(message.k); + } + return obj; + }, + + create(base?: DeepPartial): VSimRequest { + return VSimRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): VSimRequest { + const message = createBaseVSimRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.vec = object.vec?.map((e) => e) || []; + message.k = object.k ?? 0; + return message; + }, +}; + +function createBaseVSimHit(): VSimHit { + return { member: Buffer.alloc(0), score: 0 }; +} + +export const VSimHit: MessageFns = { + encode(message: VSimHit, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.member.length !== 0) { + writer.uint32(10).bytes(message.member); + } + if (message.score !== 0) { + writer.uint32(21).float(message.score); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VSimHit { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVSimHit(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.member = Buffer.from(reader.bytes()); + continue; + } + case 2: { + if (tag !== 21) { + break; + } + + message.score = reader.float(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VSimHit { + return { + member: isSet(object.member) ? Buffer.from(bytesFromBase64(object.member)) : Buffer.alloc(0), + score: isSet(object.score) ? globalThis.Number(object.score) : 0, + }; + }, + + toJSON(message: VSimHit): unknown { + const obj: any = {}; + if (message.member.length !== 0) { + obj.member = base64FromBytes(message.member); + } + if (message.score !== 0) { + obj.score = message.score; + } + return obj; + }, + + create(base?: DeepPartial): VSimHit { + return VSimHit.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): VSimHit { + const message = createBaseVSimHit(); + message.member = object.member ?? Buffer.alloc(0); + message.score = object.score ?? 0; + return message; + }, +}; + +function createBaseVSimResponse(): VSimResponse { + return { hits: [] }; +} + +export const VSimResponse: MessageFns = { + encode(message: VSimResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.hits) { + VSimHit.encode(v!, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VSimResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVSimResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.hits.push(VSimHit.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VSimResponse { + return { hits: globalThis.Array.isArray(object?.hits) ? object.hits.map((e: any) => VSimHit.fromJSON(e)) : [] }; + }, + + toJSON(message: VSimResponse): unknown { + const obj: any = {}; + if (message.hits?.length) { + obj.hits = message.hits.map((e) => VSimHit.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): VSimResponse { + return VSimResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): VSimResponse { + const message = createBaseVSimResponse(); + message.hits = object.hits?.map((e) => VSimHit.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseVCardRequest(): VCardRequest { + return { keyspace: "", name: "" }; +} + +export const VCardRequest: MessageFns = { + encode(message: VCardRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VCardRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVCardRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VCardRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: VCardRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): VCardRequest { + return VCardRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): VCardRequest { + const message = createBaseVCardRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseVCardResponse(): VCardResponse { + return { n: 0, present: false }; +} + +export const VCardResponse: MessageFns = { + encode(message: VCardResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.n !== 0) { + writer.uint32(8).int64(message.n); + } + if (message.present !== false) { + writer.uint32(16).bool(message.present); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VCardResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVCardResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.n = longToNumber(reader.int64()); + continue; + } + case 2: { + if (tag !== 16) { + break; + } + + message.present = reader.bool(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VCardResponse { + return { + n: isSet(object.n) ? globalThis.Number(object.n) : 0, + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + }; + }, + + toJSON(message: VCardResponse): unknown { + const obj: any = {}; + if (message.n !== 0) { + obj.n = Math.round(message.n); + } + if (message.present !== false) { + obj.present = message.present; + } + return obj; + }, + + create(base?: DeepPartial): VCardResponse { + return VCardResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): VCardResponse { + const message = createBaseVCardResponse(); + message.n = object.n ?? 0; + message.present = object.present ?? false; + return message; + }, +}; + +function createBaseVDimRequest(): VDimRequest { + return { keyspace: "", name: "" }; +} + +export const VDimRequest: MessageFns = { + encode(message: VDimRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VDimRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVDimRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VDimRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: VDimRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): VDimRequest { + return VDimRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): VDimRequest { + const message = createBaseVDimRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseVDimResponse(): VDimResponse { + return { dim: 0, present: false }; +} + +export const VDimResponse: MessageFns = { + encode(message: VDimResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.dim !== 0) { + writer.uint32(8).int32(message.dim); + } + if (message.present !== false) { + writer.uint32(16).bool(message.present); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VDimResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVDimResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.dim = reader.int32(); + continue; + } + case 2: { + if (tag !== 16) { + break; + } + + message.present = reader.bool(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VDimResponse { + return { + dim: isSet(object.dim) ? globalThis.Number(object.dim) : 0, + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + }; + }, + + toJSON(message: VDimResponse): unknown { + const obj: any = {}; + if (message.dim !== 0) { + obj.dim = Math.round(message.dim); + } + if (message.present !== false) { + obj.present = message.present; + } + return obj; + }, + + create(base?: DeepPartial): VDimResponse { + return VDimResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): VDimResponse { + const message = createBaseVDimResponse(); + message.dim = object.dim ?? 0; + message.present = object.present ?? false; + return message; + }, +}; + +function createBaseVEmbRequest(): VEmbRequest { + return { keyspace: "", name: "", member: Buffer.alloc(0) }; +} + +export const VEmbRequest: MessageFns = { + encode(message: VEmbRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.member.length !== 0) { + writer.uint32(26).bytes(message.member); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VEmbRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVEmbRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.member = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VEmbRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + member: isSet(object.member) ? Buffer.from(bytesFromBase64(object.member)) : Buffer.alloc(0), + }; + }, + + toJSON(message: VEmbRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.member.length !== 0) { + obj.member = base64FromBytes(message.member); + } + return obj; + }, + + create(base?: DeepPartial): VEmbRequest { + return VEmbRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): VEmbRequest { + const message = createBaseVEmbRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.member = object.member ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseVEmbResponse(): VEmbResponse { + return { vec: [], found: false }; +} + +export const VEmbResponse: MessageFns = { + encode(message: VEmbResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + writer.uint32(10).fork(); + for (const v of message.vec) { + writer.float(v); + } + writer.join(); + if (message.found !== false) { + writer.uint32(16).bool(message.found); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): VEmbResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVEmbResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag === 13) { + message.vec.push(reader.float()); + + continue; + } + + if (tag === 10) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.vec.push(reader.float()); + } + + continue; + } + + break; + } + case 2: { + if (tag !== 16) { + break; + } + + message.found = reader.bool(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): VEmbResponse { + return { + vec: globalThis.Array.isArray(object?.vec) ? object.vec.map((e: any) => globalThis.Number(e)) : [], + found: isSet(object.found) ? globalThis.Boolean(object.found) : false, + }; + }, + + toJSON(message: VEmbResponse): unknown { + const obj: any = {}; + if (message.vec?.length) { + obj.vec = message.vec; + } + if (message.found !== false) { + obj.found = message.found; + } + return obj; + }, + + create(base?: DeepPartial): VEmbResponse { + return VEmbResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): VEmbResponse { + const message = createBaseVEmbResponse(); + message.vec = object.vec?.map((e) => e) || []; + message.found = object.found ?? false; + return message; + }, +}; + +function createBaseStreamEntry(): StreamEntry { + return { id: "", payload: Buffer.alloc(0) }; +} + +export const StreamEntry: MessageFns = { + encode(message: StreamEntry, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + if (message.payload.length !== 0) { + writer.uint32(18).bytes(message.payload); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): StreamEntry { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseStreamEntry(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.payload = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): StreamEntry { + return { + id: isSet(object.id) ? globalThis.String(object.id) : "", + payload: isSet(object.payload) ? Buffer.from(bytesFromBase64(object.payload)) : Buffer.alloc(0), + }; + }, + + toJSON(message: StreamEntry): unknown { + const obj: any = {}; + if (message.id !== "") { + obj.id = message.id; + } + if (message.payload.length !== 0) { + obj.payload = base64FromBytes(message.payload); + } + return obj; + }, + + create(base?: DeepPartial): StreamEntry { + return StreamEntry.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): StreamEntry { + const message = createBaseStreamEntry(); + message.id = object.id ?? ""; + message.payload = object.payload ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseXAddRequest(): XAddRequest { + return { keyspace: "", name: "", payload: Buffer.alloc(0) }; +} + +export const XAddRequest: MessageFns = { + encode(message: XAddRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.payload.length !== 0) { + writer.uint32(26).bytes(message.payload); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): XAddRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseXAddRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.payload = Buffer.from(reader.bytes()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): XAddRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + payload: isSet(object.payload) ? Buffer.from(bytesFromBase64(object.payload)) : Buffer.alloc(0), + }; + }, + + toJSON(message: XAddRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.payload.length !== 0) { + obj.payload = base64FromBytes(message.payload); + } + return obj; + }, + + create(base?: DeepPartial): XAddRequest { + return XAddRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): XAddRequest { + const message = createBaseXAddRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.payload = object.payload ?? Buffer.alloc(0); + return message; + }, +}; + +function createBaseXAddResponse(): XAddResponse { + return { id: "" }; +} + +export const XAddResponse: MessageFns = { + encode(message: XAddResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.id !== "") { + writer.uint32(10).string(message.id); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): XAddResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseXAddResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.id = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): XAddResponse { + return { id: isSet(object.id) ? globalThis.String(object.id) : "" }; + }, + + toJSON(message: XAddResponse): unknown { + const obj: any = {}; + if (message.id !== "") { + obj.id = message.id; + } + return obj; + }, + + create(base?: DeepPartial): XAddResponse { + return XAddResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): XAddResponse { + const message = createBaseXAddResponse(); + message.id = object.id ?? ""; + return message; + }, +}; + +function createBaseXRangeRequest(): XRangeRequest { + return { keyspace: "", name: "", start: "", end: "", count: 0 }; +} + +export const XRangeRequest: MessageFns = { + encode(message: XRangeRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.start !== "") { + writer.uint32(26).string(message.start); + } + if (message.end !== "") { + writer.uint32(34).string(message.end); + } + if (message.count !== 0) { + writer.uint32(40).int32(message.count); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): XRangeRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseXRangeRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.start = reader.string(); + continue; + } + case 4: { + if (tag !== 34) { + break; + } + + message.end = reader.string(); + continue; + } + case 5: { + if (tag !== 40) { + break; + } + + message.count = reader.int32(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): XRangeRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + start: isSet(object.start) ? globalThis.String(object.start) : "", + end: isSet(object.end) ? globalThis.String(object.end) : "", + count: isSet(object.count) ? globalThis.Number(object.count) : 0, + }; + }, + + toJSON(message: XRangeRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.start !== "") { + obj.start = message.start; + } + if (message.end !== "") { + obj.end = message.end; + } + if (message.count !== 0) { + obj.count = Math.round(message.count); + } + return obj; + }, + + create(base?: DeepPartial): XRangeRequest { + return XRangeRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): XRangeRequest { + const message = createBaseXRangeRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.start = object.start ?? ""; + message.end = object.end ?? ""; + message.count = object.count ?? 0; + return message; + }, +}; + +function createBaseXRevRangeRequest(): XRevRangeRequest { + return { keyspace: "", name: "", start: "", end: "", count: 0 }; +} + +export const XRevRangeRequest: MessageFns = { + encode(message: XRevRangeRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.start !== "") { + writer.uint32(26).string(message.start); + } + if (message.end !== "") { + writer.uint32(34).string(message.end); + } + if (message.count !== 0) { + writer.uint32(40).int32(message.count); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): XRevRangeRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseXRevRangeRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.start = reader.string(); + continue; + } + case 4: { + if (tag !== 34) { + break; + } + + message.end = reader.string(); + continue; + } + case 5: { + if (tag !== 40) { + break; + } + + message.count = reader.int32(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): XRevRangeRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + start: isSet(object.start) ? globalThis.String(object.start) : "", + end: isSet(object.end) ? globalThis.String(object.end) : "", + count: isSet(object.count) ? globalThis.Number(object.count) : 0, + }; + }, + + toJSON(message: XRevRangeRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.start !== "") { + obj.start = message.start; + } + if (message.end !== "") { + obj.end = message.end; + } + if (message.count !== 0) { + obj.count = Math.round(message.count); + } + return obj; + }, + + create(base?: DeepPartial): XRevRangeRequest { + return XRevRangeRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): XRevRangeRequest { + const message = createBaseXRevRangeRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.start = object.start ?? ""; + message.end = object.end ?? ""; + message.count = object.count ?? 0; + return message; + }, +}; + +function createBaseXRangeResponse(): XRangeResponse { + return { entries: [] }; +} + +export const XRangeResponse: MessageFns = { + encode(message: XRangeResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.entries) { + StreamEntry.encode(v!, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): XRangeResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseXRangeResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.entries.push(StreamEntry.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): XRangeResponse { + return { + entries: globalThis.Array.isArray(object?.entries) ? object.entries.map((e: any) => StreamEntry.fromJSON(e)) : [], + }; + }, + + toJSON(message: XRangeResponse): unknown { + const obj: any = {}; + if (message.entries?.length) { + obj.entries = message.entries.map((e) => StreamEntry.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): XRangeResponse { + return XRangeResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): XRangeResponse { + const message = createBaseXRangeResponse(); + message.entries = object.entries?.map((e) => StreamEntry.fromPartial(e)) || []; + return message; + }, +}; + +function createBaseXLenRequest(): XLenRequest { + return { keyspace: "", name: "" }; +} + +export const XLenRequest: MessageFns = { + encode(message: XLenRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): XLenRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseXLenRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): XLenRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: XLenRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): XLenRequest { + return XLenRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): XLenRequest { + const message = createBaseXLenRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + +function createBaseXLenResponse(): XLenResponse { + return { n: 0, present: false }; +} + +export const XLenResponse: MessageFns = { + encode(message: XLenResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.n !== 0) { + writer.uint32(8).int64(message.n); + } + if (message.present !== false) { + writer.uint32(16).bool(message.present); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): XLenResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseXLenResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 8) { + break; + } + + message.n = longToNumber(reader.int64()); + continue; + } + case 2: { + if (tag !== 16) { + break; + } + + message.present = reader.bool(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): XLenResponse { + return { + n: isSet(object.n) ? globalThis.Number(object.n) : 0, + present: isSet(object.present) ? globalThis.Boolean(object.present) : false, + }; + }, + + toJSON(message: XLenResponse): unknown { + const obj: any = {}; + if (message.n !== 0) { + obj.n = Math.round(message.n); + } + if (message.present !== false) { + obj.present = message.present; + } + return obj; + }, + + create(base?: DeepPartial): XLenResponse { + return XLenResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): XLenResponse { + const message = createBaseXLenResponse(); + message.n = object.n ?? 0; + message.present = object.present ?? false; + return message; + }, +}; + +function createBaseXDelRequest(): XDelRequest { + return { keyspace: "", name: "", id: "" }; +} + +export const XDelRequest: MessageFns = { + encode(message: XDelRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.id !== "") { + writer.uint32(26).string(message.id); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): XDelRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseXDelRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.id = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): XDelRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + id: isSet(object.id) ? globalThis.String(object.id) : "", + }; + }, + + toJSON(message: XDelRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.id !== "") { + obj.id = message.id; + } + return obj; + }, + + create(base?: DeepPartial): XDelRequest { + return XDelRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): XDelRequest { + const message = createBaseXDelRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.id = object.id ?? ""; + return message; + }, +}; + +function createBaseXDelResponse(): XDelResponse { + return {}; +} + +export const XDelResponse: MessageFns = { + encode(_: XDelResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): XDelResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseXDelResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): XDelResponse { + return {}; + }, + + toJSON(_: XDelResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): XDelResponse { + return XDelResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): XDelResponse { + const message = createBaseXDelResponse(); + return message; + }, +}; + +function createBaseXTrimRequest(): XTrimRequest { + return { keyspace: "", name: "", maxLen: 0 }; +} + +export const XTrimRequest: MessageFns = { + encode(message: XTrimRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.keyspace !== "") { + writer.uint32(10).string(message.keyspace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + if (message.maxLen !== 0) { + writer.uint32(24).int32(message.maxLen); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): XTrimRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseXTrimRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.keyspace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + case 3: { + if (tag !== 24) { + break; + } + + message.maxLen = reader.int32(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): XTrimRequest { + return { + keyspace: isSet(object.keyspace) ? globalThis.String(object.keyspace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + maxLen: isSet(object.maxLen) ? globalThis.Number(object.maxLen) : 0, + }; + }, + + toJSON(message: XTrimRequest): unknown { + const obj: any = {}; + if (message.keyspace !== "") { + obj.keyspace = message.keyspace; + } + if (message.name !== "") { + obj.name = message.name; + } + if (message.maxLen !== 0) { + obj.maxLen = Math.round(message.maxLen); + } + return obj; + }, + + create(base?: DeepPartial): XTrimRequest { + return XTrimRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): XTrimRequest { + const message = createBaseXTrimRequest(); + message.keyspace = object.keyspace ?? ""; + message.name = object.name ?? ""; + message.maxLen = object.maxLen ?? 0; + return message; + }, +}; + +function createBaseXTrimResponse(): XTrimResponse { + return {}; +} + +export const XTrimResponse: MessageFns = { + encode(_: XTrimResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): XTrimResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseXTrimResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): XTrimResponse { + return {}; + }, + + toJSON(_: XTrimResponse): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): XTrimResponse { + return XTrimResponse.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): XTrimResponse { + const message = createBaseXTrimResponse(); + return message; + }, +}; + +/** Cache is the application-facing API (not the peer mesh). */ +export type CacheService = typeof CacheService; +export const CacheService = { + get: { + path: "/supercache.cache.v1.Cache/Get", + requestStream: false, + responseStream: false, + requestSerialize: (value: GetRequest): Buffer => Buffer.from(GetRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): GetRequest => GetRequest.decode(value), + responseSerialize: (value: GetResponse): Buffer => Buffer.from(GetResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): GetResponse => GetResponse.decode(value), + }, + put: { + path: "/supercache.cache.v1.Cache/Put", + requestStream: false, + responseStream: false, + requestSerialize: (value: PutRequest): Buffer => Buffer.from(PutRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): PutRequest => PutRequest.decode(value), + responseSerialize: (value: PutResponse): Buffer => Buffer.from(PutResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): PutResponse => PutResponse.decode(value), + }, + putMany: { + path: "/supercache.cache.v1.Cache/PutMany", + requestStream: false, + responseStream: false, + requestSerialize: (value: PutManyRequest): Buffer => Buffer.from(PutManyRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): PutManyRequest => PutManyRequest.decode(value), + responseSerialize: (value: PutManyResponse): Buffer => Buffer.from(PutManyResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): PutManyResponse => PutManyResponse.decode(value), + }, + delete: { + path: "/supercache.cache.v1.Cache/Delete", + requestStream: false, + responseStream: false, + requestSerialize: (value: DeleteRequest): Buffer => Buffer.from(DeleteRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): DeleteRequest => DeleteRequest.decode(value), + responseSerialize: (value: DeleteResponse): Buffer => Buffer.from(DeleteResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): DeleteResponse => DeleteResponse.decode(value), + }, + deleteMany: { + path: "/supercache.cache.v1.Cache/DeleteMany", + requestStream: false, + responseStream: false, + requestSerialize: (value: DeleteManyRequest): Buffer => Buffer.from(DeleteManyRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): DeleteManyRequest => DeleteManyRequest.decode(value), + responseSerialize: (value: DeleteManyResponse): Buffer => Buffer.from(DeleteManyResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): DeleteManyResponse => DeleteManyResponse.decode(value), + }, + bloomAdd: { + path: "/supercache.cache.v1.Cache/BloomAdd", + requestStream: false, + responseStream: false, + requestSerialize: (value: BloomAddRequest): Buffer => Buffer.from(BloomAddRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): BloomAddRequest => BloomAddRequest.decode(value), + responseSerialize: (value: BloomAddResponse): Buffer => Buffer.from(BloomAddResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): BloomAddResponse => BloomAddResponse.decode(value), + }, + bloomTest: { + path: "/supercache.cache.v1.Cache/BloomTest", + requestStream: false, + responseStream: false, + requestSerialize: (value: BloomTestRequest): Buffer => Buffer.from(BloomTestRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): BloomTestRequest => BloomTestRequest.decode(value), + responseSerialize: (value: BloomTestResponse): Buffer => Buffer.from(BloomTestResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): BloomTestResponse => BloomTestResponse.decode(value), + }, + setAdd: { + path: "/supercache.cache.v1.Cache/SetAdd", + requestStream: false, + responseStream: false, + requestSerialize: (value: SetAddRequest): Buffer => Buffer.from(SetAddRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): SetAddRequest => SetAddRequest.decode(value), + responseSerialize: (value: SetAddResponse): Buffer => Buffer.from(SetAddResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): SetAddResponse => SetAddResponse.decode(value), + }, + setRemove: { + path: "/supercache.cache.v1.Cache/SetRemove", + requestStream: false, + responseStream: false, + requestSerialize: (value: SetRemoveRequest): Buffer => Buffer.from(SetRemoveRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): SetRemoveRequest => SetRemoveRequest.decode(value), + responseSerialize: (value: SetRemoveResponse): Buffer => Buffer.from(SetRemoveResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): SetRemoveResponse => SetRemoveResponse.decode(value), + }, + setContains: { + path: "/supercache.cache.v1.Cache/SetContains", + requestStream: false, + responseStream: false, + requestSerialize: (value: SetContainsRequest): Buffer => Buffer.from(SetContainsRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): SetContainsRequest => SetContainsRequest.decode(value), + responseSerialize: (value: SetContainsResponse): Buffer => Buffer.from(SetContainsResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): SetContainsResponse => SetContainsResponse.decode(value), + }, + setCard: { + path: "/supercache.cache.v1.Cache/SetCard", + requestStream: false, + responseStream: false, + requestSerialize: (value: SetCardRequest): Buffer => Buffer.from(SetCardRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): SetCardRequest => SetCardRequest.decode(value), + responseSerialize: (value: SetCardResponse): Buffer => Buffer.from(SetCardResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): SetCardResponse => SetCardResponse.decode(value), + }, + setMembers: { + path: "/supercache.cache.v1.Cache/SetMembers", + requestStream: false, + responseStream: false, + requestSerialize: (value: SetMembersRequest): Buffer => Buffer.from(SetMembersRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): SetMembersRequest => SetMembersRequest.decode(value), + responseSerialize: (value: SetMembersResponse): Buffer => Buffer.from(SetMembersResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): SetMembersResponse => SetMembersResponse.decode(value), + }, + zAdd: { + path: "/supercache.cache.v1.Cache/ZAdd", + requestStream: false, + responseStream: false, + requestSerialize: (value: ZAddRequest): Buffer => Buffer.from(ZAddRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): ZAddRequest => ZAddRequest.decode(value), + responseSerialize: (value: ZAddResponse): Buffer => Buffer.from(ZAddResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): ZAddResponse => ZAddResponse.decode(value), + }, + zRem: { + path: "/supercache.cache.v1.Cache/ZRem", + requestStream: false, + responseStream: false, + requestSerialize: (value: ZRemRequest): Buffer => Buffer.from(ZRemRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): ZRemRequest => ZRemRequest.decode(value), + responseSerialize: (value: ZRemResponse): Buffer => Buffer.from(ZRemResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): ZRemResponse => ZRemResponse.decode(value), + }, + zScore: { + path: "/supercache.cache.v1.Cache/ZScore", + requestStream: false, + responseStream: false, + requestSerialize: (value: ZScoreRequest): Buffer => Buffer.from(ZScoreRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): ZScoreRequest => ZScoreRequest.decode(value), + responseSerialize: (value: ZScoreResponse): Buffer => Buffer.from(ZScoreResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): ZScoreResponse => ZScoreResponse.decode(value), + }, + zCard: { + path: "/supercache.cache.v1.Cache/ZCard", + requestStream: false, + responseStream: false, + requestSerialize: (value: ZCardRequest): Buffer => Buffer.from(ZCardRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): ZCardRequest => ZCardRequest.decode(value), + responseSerialize: (value: ZCardResponse): Buffer => Buffer.from(ZCardResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): ZCardResponse => ZCardResponse.decode(value), + }, + zRange: { + path: "/supercache.cache.v1.Cache/ZRange", + requestStream: false, + responseStream: false, + requestSerialize: (value: ZRangeRequest): Buffer => Buffer.from(ZRangeRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): ZRangeRequest => ZRangeRequest.decode(value), + responseSerialize: (value: ZRangeResponse): Buffer => Buffer.from(ZRangeResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): ZRangeResponse => ZRangeResponse.decode(value), + }, + zRangeByScore: { + path: "/supercache.cache.v1.Cache/ZRangeByScore", + requestStream: false, + responseStream: false, + requestSerialize: (value: ZRangeByScoreRequest): Buffer => Buffer.from(ZRangeByScoreRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): ZRangeByScoreRequest => ZRangeByScoreRequest.decode(value), + responseSerialize: (value: ZRangeResponse): Buffer => Buffer.from(ZRangeResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): ZRangeResponse => ZRangeResponse.decode(value), + }, + geoAdd: { + path: "/supercache.cache.v1.Cache/GeoAdd", + requestStream: false, + responseStream: false, + requestSerialize: (value: GeoAddRequest): Buffer => Buffer.from(GeoAddRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): GeoAddRequest => GeoAddRequest.decode(value), + responseSerialize: (value: GeoAddResponse): Buffer => Buffer.from(GeoAddResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): GeoAddResponse => GeoAddResponse.decode(value), + }, + geoRem: { + path: "/supercache.cache.v1.Cache/GeoRem", + requestStream: false, + responseStream: false, + requestSerialize: (value: GeoRemRequest): Buffer => Buffer.from(GeoRemRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): GeoRemRequest => GeoRemRequest.decode(value), + responseSerialize: (value: GeoRemResponse): Buffer => Buffer.from(GeoRemResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): GeoRemResponse => GeoRemResponse.decode(value), + }, + geoPos: { + path: "/supercache.cache.v1.Cache/GeoPos", + requestStream: false, + responseStream: false, + requestSerialize: (value: GeoPosRequest): Buffer => Buffer.from(GeoPosRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): GeoPosRequest => GeoPosRequest.decode(value), + responseSerialize: (value: GeoPosResponse): Buffer => Buffer.from(GeoPosResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): GeoPosResponse => GeoPosResponse.decode(value), + }, + geoCard: { + path: "/supercache.cache.v1.Cache/GeoCard", + requestStream: false, + responseStream: false, + requestSerialize: (value: GeoCardRequest): Buffer => Buffer.from(GeoCardRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): GeoCardRequest => GeoCardRequest.decode(value), + responseSerialize: (value: GeoCardResponse): Buffer => Buffer.from(GeoCardResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): GeoCardResponse => GeoCardResponse.decode(value), + }, + geoDist: { + path: "/supercache.cache.v1.Cache/GeoDist", + requestStream: false, + responseStream: false, + requestSerialize: (value: GeoDistRequest): Buffer => Buffer.from(GeoDistRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): GeoDistRequest => GeoDistRequest.decode(value), + responseSerialize: (value: GeoDistResponse): Buffer => Buffer.from(GeoDistResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): GeoDistResponse => GeoDistResponse.decode(value), + }, + geoRadius: { + path: "/supercache.cache.v1.Cache/GeoRadius", + requestStream: false, + responseStream: false, + requestSerialize: (value: GeoRadiusRequest): Buffer => Buffer.from(GeoRadiusRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): GeoRadiusRequest => GeoRadiusRequest.decode(value), + responseSerialize: (value: GeoRadiusResponse): Buffer => Buffer.from(GeoRadiusResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): GeoRadiusResponse => GeoRadiusResponse.decode(value), + }, + lPush: { + path: "/supercache.cache.v1.Cache/LPush", + requestStream: false, + responseStream: false, + requestSerialize: (value: LPushRequest): Buffer => Buffer.from(LPushRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): LPushRequest => LPushRequest.decode(value), + responseSerialize: (value: LPushResponse): Buffer => Buffer.from(LPushResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): LPushResponse => LPushResponse.decode(value), + }, + rPush: { + path: "/supercache.cache.v1.Cache/RPush", + requestStream: false, + responseStream: false, + requestSerialize: (value: RPushRequest): Buffer => Buffer.from(RPushRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): RPushRequest => RPushRequest.decode(value), + responseSerialize: (value: RPushResponse): Buffer => Buffer.from(RPushResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): RPushResponse => RPushResponse.decode(value), + }, + lPop: { + path: "/supercache.cache.v1.Cache/LPop", + requestStream: false, + responseStream: false, + requestSerialize: (value: LPopRequest): Buffer => Buffer.from(LPopRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): LPopRequest => LPopRequest.decode(value), + responseSerialize: (value: LPopResponse): Buffer => Buffer.from(LPopResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): LPopResponse => LPopResponse.decode(value), + }, + rPop: { + path: "/supercache.cache.v1.Cache/RPop", + requestStream: false, + responseStream: false, + requestSerialize: (value: RPopRequest): Buffer => Buffer.from(RPopRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): RPopRequest => RPopRequest.decode(value), + responseSerialize: (value: RPopResponse): Buffer => Buffer.from(RPopResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): RPopResponse => RPopResponse.decode(value), + }, + lLen: { + path: "/supercache.cache.v1.Cache/LLen", + requestStream: false, + responseStream: false, + requestSerialize: (value: LLenRequest): Buffer => Buffer.from(LLenRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): LLenRequest => LLenRequest.decode(value), + responseSerialize: (value: LLenResponse): Buffer => Buffer.from(LLenResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): LLenResponse => LLenResponse.decode(value), + }, + lIndex: { + path: "/supercache.cache.v1.Cache/LIndex", + requestStream: false, + responseStream: false, + requestSerialize: (value: LIndexRequest): Buffer => Buffer.from(LIndexRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): LIndexRequest => LIndexRequest.decode(value), + responseSerialize: (value: LIndexResponse): Buffer => Buffer.from(LIndexResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): LIndexResponse => LIndexResponse.decode(value), + }, + lRange: { + path: "/supercache.cache.v1.Cache/LRange", + requestStream: false, + responseStream: false, + requestSerialize: (value: LRangeRequest): Buffer => Buffer.from(LRangeRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): LRangeRequest => LRangeRequest.decode(value), + responseSerialize: (value: LRangeResponse): Buffer => Buffer.from(LRangeResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): LRangeResponse => LRangeResponse.decode(value), + }, + hSet: { + path: "/supercache.cache.v1.Cache/HSet", + requestStream: false, + responseStream: false, + requestSerialize: (value: HSetRequest): Buffer => Buffer.from(HSetRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): HSetRequest => HSetRequest.decode(value), + responseSerialize: (value: HSetResponse): Buffer => Buffer.from(HSetResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): HSetResponse => HSetResponse.decode(value), + }, + hGet: { + path: "/supercache.cache.v1.Cache/HGet", + requestStream: false, + responseStream: false, + requestSerialize: (value: HGetRequest): Buffer => Buffer.from(HGetRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): HGetRequest => HGetRequest.decode(value), + responseSerialize: (value: HGetResponse): Buffer => Buffer.from(HGetResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): HGetResponse => HGetResponse.decode(value), + }, + hDel: { + path: "/supercache.cache.v1.Cache/HDel", + requestStream: false, + responseStream: false, + requestSerialize: (value: HDelRequest): Buffer => Buffer.from(HDelRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): HDelRequest => HDelRequest.decode(value), + responseSerialize: (value: HDelResponse): Buffer => Buffer.from(HDelResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): HDelResponse => HDelResponse.decode(value), + }, + hExists: { + path: "/supercache.cache.v1.Cache/HExists", + requestStream: false, + responseStream: false, + requestSerialize: (value: HExistsRequest): Buffer => Buffer.from(HExistsRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): HExistsRequest => HExistsRequest.decode(value), + responseSerialize: (value: HExistsResponse): Buffer => Buffer.from(HExistsResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): HExistsResponse => HExistsResponse.decode(value), + }, + hLen: { + path: "/supercache.cache.v1.Cache/HLen", + requestStream: false, + responseStream: false, + requestSerialize: (value: HLenRequest): Buffer => Buffer.from(HLenRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): HLenRequest => HLenRequest.decode(value), + responseSerialize: (value: HLenResponse): Buffer => Buffer.from(HLenResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): HLenResponse => HLenResponse.decode(value), + }, + hGetAll: { + path: "/supercache.cache.v1.Cache/HGetAll", + requestStream: false, + responseStream: false, + requestSerialize: (value: HGetAllRequest): Buffer => Buffer.from(HGetAllRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): HGetAllRequest => HGetAllRequest.decode(value), + responseSerialize: (value: HGetAllResponse): Buffer => Buffer.from(HGetAllResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): HGetAllResponse => HGetAllResponse.decode(value), + }, + incr: { + path: "/supercache.cache.v1.Cache/Incr", + requestStream: false, + responseStream: false, + requestSerialize: (value: IncrRequest): Buffer => Buffer.from(IncrRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): IncrRequest => IncrRequest.decode(value), + responseSerialize: (value: IncrResponse): Buffer => Buffer.from(IncrResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): IncrResponse => IncrResponse.decode(value), + }, + counterGet: { + path: "/supercache.cache.v1.Cache/CounterGet", + requestStream: false, + responseStream: false, + requestSerialize: (value: CounterGetRequest): Buffer => Buffer.from(CounterGetRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): CounterGetRequest => CounterGetRequest.decode(value), + responseSerialize: (value: CounterGetResponse): Buffer => Buffer.from(CounterGetResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): CounterGetResponse => CounterGetResponse.decode(value), + }, + jsonSet: { + path: "/supercache.cache.v1.Cache/JsonSet", + requestStream: false, + responseStream: false, + requestSerialize: (value: JsonSetRequest): Buffer => Buffer.from(JsonSetRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): JsonSetRequest => JsonSetRequest.decode(value), + responseSerialize: (value: JsonSetResponse): Buffer => Buffer.from(JsonSetResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): JsonSetResponse => JsonSetResponse.decode(value), + }, + jsonGet: { + path: "/supercache.cache.v1.Cache/JsonGet", + requestStream: false, + responseStream: false, + requestSerialize: (value: JsonGetRequest): Buffer => Buffer.from(JsonGetRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): JsonGetRequest => JsonGetRequest.decode(value), + responseSerialize: (value: JsonGetResponse): Buffer => Buffer.from(JsonGetResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): JsonGetResponse => JsonGetResponse.decode(value), + }, + jsonDel: { + path: "/supercache.cache.v1.Cache/JsonDel", + requestStream: false, + responseStream: false, + requestSerialize: (value: JsonDelRequest): Buffer => Buffer.from(JsonDelRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): JsonDelRequest => JsonDelRequest.decode(value), + responseSerialize: (value: JsonDelResponse): Buffer => Buffer.from(JsonDelResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): JsonDelResponse => JsonDelResponse.decode(value), + }, + bitSet: { + path: "/supercache.cache.v1.Cache/BitSet", + requestStream: false, + responseStream: false, + requestSerialize: (value: BitSetRequest): Buffer => Buffer.from(BitSetRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): BitSetRequest => BitSetRequest.decode(value), + responseSerialize: (value: BitSetResponse): Buffer => Buffer.from(BitSetResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): BitSetResponse => BitSetResponse.decode(value), + }, + bitGet: { + path: "/supercache.cache.v1.Cache/BitGet", + requestStream: false, + responseStream: false, + requestSerialize: (value: BitGetRequest): Buffer => Buffer.from(BitGetRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): BitGetRequest => BitGetRequest.decode(value), + responseSerialize: (value: BitGetResponse): Buffer => Buffer.from(BitGetResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): BitGetResponse => BitGetResponse.decode(value), + }, + bitCount: { + path: "/supercache.cache.v1.Cache/BitCount", + requestStream: false, + responseStream: false, + requestSerialize: (value: BitCountRequest): Buffer => Buffer.from(BitCountRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): BitCountRequest => BitCountRequest.decode(value), + responseSerialize: (value: BitCountResponse): Buffer => Buffer.from(BitCountResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): BitCountResponse => BitCountResponse.decode(value), + }, + bitPos: { + path: "/supercache.cache.v1.Cache/BitPos", + requestStream: false, + responseStream: false, + requestSerialize: (value: BitPosRequest): Buffer => Buffer.from(BitPosRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): BitPosRequest => BitPosRequest.decode(value), + responseSerialize: (value: BitPosResponse): Buffer => Buffer.from(BitPosResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): BitPosResponse => BitPosResponse.decode(value), + }, + hllAdd: { + path: "/supercache.cache.v1.Cache/HLLAdd", + requestStream: false, + responseStream: false, + requestSerialize: (value: HLLAddRequest): Buffer => Buffer.from(HLLAddRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): HLLAddRequest => HLLAddRequest.decode(value), + responseSerialize: (value: HLLAddResponse): Buffer => Buffer.from(HLLAddResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): HLLAddResponse => HLLAddResponse.decode(value), + }, + hllCount: { + path: "/supercache.cache.v1.Cache/HLLCount", + requestStream: false, + responseStream: false, + requestSerialize: (value: HLLCountRequest): Buffer => Buffer.from(HLLCountRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): HLLCountRequest => HLLCountRequest.decode(value), + responseSerialize: (value: HLLCountResponse): Buffer => Buffer.from(HLLCountResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): HLLCountResponse => HLLCountResponse.decode(value), + }, + topKAdd: { + path: "/supercache.cache.v1.Cache/TopKAdd", + requestStream: false, + responseStream: false, + requestSerialize: (value: TopKAddRequest): Buffer => Buffer.from(TopKAddRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): TopKAddRequest => TopKAddRequest.decode(value), + responseSerialize: (value: TopKAddResponse): Buffer => Buffer.from(TopKAddResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): TopKAddResponse => TopKAddResponse.decode(value), + }, + topKList: { + path: "/supercache.cache.v1.Cache/TopKList", + requestStream: false, + responseStream: false, + requestSerialize: (value: TopKListRequest): Buffer => Buffer.from(TopKListRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): TopKListRequest => TopKListRequest.decode(value), + responseSerialize: (value: TopKListResponse): Buffer => Buffer.from(TopKListResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): TopKListResponse => TopKListResponse.decode(value), + }, + cmsIncr: { + path: "/supercache.cache.v1.Cache/CMSIncr", + requestStream: false, + responseStream: false, + requestSerialize: (value: CMSIncrRequest): Buffer => Buffer.from(CMSIncrRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): CMSIncrRequest => CMSIncrRequest.decode(value), + responseSerialize: (value: CMSIncrResponse): Buffer => Buffer.from(CMSIncrResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): CMSIncrResponse => CMSIncrResponse.decode(value), + }, + cmsQuery: { + path: "/supercache.cache.v1.Cache/CMSQuery", + requestStream: false, + responseStream: false, + requestSerialize: (value: CMSQueryRequest): Buffer => Buffer.from(CMSQueryRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): CMSQueryRequest => CMSQueryRequest.decode(value), + responseSerialize: (value: CMSQueryResponse): Buffer => Buffer.from(CMSQueryResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): CMSQueryResponse => CMSQueryResponse.decode(value), + }, + vAdd: { + path: "/supercache.cache.v1.Cache/VAdd", + requestStream: false, + responseStream: false, + requestSerialize: (value: VAddRequest): Buffer => Buffer.from(VAddRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): VAddRequest => VAddRequest.decode(value), + responseSerialize: (value: VAddResponse): Buffer => Buffer.from(VAddResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): VAddResponse => VAddResponse.decode(value), + }, + vRem: { + path: "/supercache.cache.v1.Cache/VRem", + requestStream: false, + responseStream: false, + requestSerialize: (value: VRemRequest): Buffer => Buffer.from(VRemRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): VRemRequest => VRemRequest.decode(value), + responseSerialize: (value: VRemResponse): Buffer => Buffer.from(VRemResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): VRemResponse => VRemResponse.decode(value), + }, + vSim: { + path: "/supercache.cache.v1.Cache/VSim", + requestStream: false, + responseStream: false, + requestSerialize: (value: VSimRequest): Buffer => Buffer.from(VSimRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): VSimRequest => VSimRequest.decode(value), + responseSerialize: (value: VSimResponse): Buffer => Buffer.from(VSimResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): VSimResponse => VSimResponse.decode(value), + }, + vCard: { + path: "/supercache.cache.v1.Cache/VCard", + requestStream: false, + responseStream: false, + requestSerialize: (value: VCardRequest): Buffer => Buffer.from(VCardRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): VCardRequest => VCardRequest.decode(value), + responseSerialize: (value: VCardResponse): Buffer => Buffer.from(VCardResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): VCardResponse => VCardResponse.decode(value), + }, + vDim: { + path: "/supercache.cache.v1.Cache/VDim", + requestStream: false, + responseStream: false, + requestSerialize: (value: VDimRequest): Buffer => Buffer.from(VDimRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): VDimRequest => VDimRequest.decode(value), + responseSerialize: (value: VDimResponse): Buffer => Buffer.from(VDimResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): VDimResponse => VDimResponse.decode(value), + }, + vEmb: { + path: "/supercache.cache.v1.Cache/VEmb", + requestStream: false, + responseStream: false, + requestSerialize: (value: VEmbRequest): Buffer => Buffer.from(VEmbRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): VEmbRequest => VEmbRequest.decode(value), + responseSerialize: (value: VEmbResponse): Buffer => Buffer.from(VEmbResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): VEmbResponse => VEmbResponse.decode(value), + }, + xAdd: { + path: "/supercache.cache.v1.Cache/XAdd", + requestStream: false, + responseStream: false, + requestSerialize: (value: XAddRequest): Buffer => Buffer.from(XAddRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): XAddRequest => XAddRequest.decode(value), + responseSerialize: (value: XAddResponse): Buffer => Buffer.from(XAddResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): XAddResponse => XAddResponse.decode(value), + }, + xRange: { + path: "/supercache.cache.v1.Cache/XRange", + requestStream: false, + responseStream: false, + requestSerialize: (value: XRangeRequest): Buffer => Buffer.from(XRangeRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): XRangeRequest => XRangeRequest.decode(value), + responseSerialize: (value: XRangeResponse): Buffer => Buffer.from(XRangeResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): XRangeResponse => XRangeResponse.decode(value), + }, + xRevRange: { + path: "/supercache.cache.v1.Cache/XRevRange", + requestStream: false, + responseStream: false, + requestSerialize: (value: XRevRangeRequest): Buffer => Buffer.from(XRevRangeRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): XRevRangeRequest => XRevRangeRequest.decode(value), + responseSerialize: (value: XRangeResponse): Buffer => Buffer.from(XRangeResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): XRangeResponse => XRangeResponse.decode(value), + }, + xLen: { + path: "/supercache.cache.v1.Cache/XLen", + requestStream: false, + responseStream: false, + requestSerialize: (value: XLenRequest): Buffer => Buffer.from(XLenRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): XLenRequest => XLenRequest.decode(value), + responseSerialize: (value: XLenResponse): Buffer => Buffer.from(XLenResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): XLenResponse => XLenResponse.decode(value), + }, + xDel: { + path: "/supercache.cache.v1.Cache/XDel", + requestStream: false, + responseStream: false, + requestSerialize: (value: XDelRequest): Buffer => Buffer.from(XDelRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): XDelRequest => XDelRequest.decode(value), + responseSerialize: (value: XDelResponse): Buffer => Buffer.from(XDelResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): XDelResponse => XDelResponse.decode(value), + }, + xTrim: { + path: "/supercache.cache.v1.Cache/XTrim", + requestStream: false, + responseStream: false, + requestSerialize: (value: XTrimRequest): Buffer => Buffer.from(XTrimRequest.encode(value).finish()), + requestDeserialize: (value: Buffer): XTrimRequest => XTrimRequest.decode(value), + responseSerialize: (value: XTrimResponse): Buffer => Buffer.from(XTrimResponse.encode(value).finish()), + responseDeserialize: (value: Buffer): XTrimResponse => XTrimResponse.decode(value), + }, +} as const; + +export interface CacheServer extends UntypedServiceImplementation { + get: handleUnaryCall; + put: handleUnaryCall; + putMany: handleUnaryCall; + delete: handleUnaryCall; + deleteMany: handleUnaryCall; + bloomAdd: handleUnaryCall; + bloomTest: handleUnaryCall; + setAdd: handleUnaryCall; + setRemove: handleUnaryCall; + setContains: handleUnaryCall; + setCard: handleUnaryCall; + setMembers: handleUnaryCall; + zAdd: handleUnaryCall; + zRem: handleUnaryCall; + zScore: handleUnaryCall; + zCard: handleUnaryCall; + zRange: handleUnaryCall; + zRangeByScore: handleUnaryCall; + geoAdd: handleUnaryCall; + geoRem: handleUnaryCall; + geoPos: handleUnaryCall; + geoCard: handleUnaryCall; + geoDist: handleUnaryCall; + geoRadius: handleUnaryCall; + lPush: handleUnaryCall; + rPush: handleUnaryCall; + lPop: handleUnaryCall; + rPop: handleUnaryCall; + lLen: handleUnaryCall; + lIndex: handleUnaryCall; + lRange: handleUnaryCall; + hSet: handleUnaryCall; + hGet: handleUnaryCall; + hDel: handleUnaryCall; + hExists: handleUnaryCall; + hLen: handleUnaryCall; + hGetAll: handleUnaryCall; + incr: handleUnaryCall; + counterGet: handleUnaryCall; + jsonSet: handleUnaryCall; + jsonGet: handleUnaryCall; + jsonDel: handleUnaryCall; + bitSet: handleUnaryCall; + bitGet: handleUnaryCall; + bitCount: handleUnaryCall; + bitPos: handleUnaryCall; + hllAdd: handleUnaryCall; + hllCount: handleUnaryCall; + topKAdd: handleUnaryCall; + topKList: handleUnaryCall; + cmsIncr: handleUnaryCall; + cmsQuery: handleUnaryCall; + vAdd: handleUnaryCall; + vRem: handleUnaryCall; + vSim: handleUnaryCall; + vCard: handleUnaryCall; + vDim: handleUnaryCall; + vEmb: handleUnaryCall; + xAdd: handleUnaryCall; + xRange: handleUnaryCall; + xRevRange: handleUnaryCall; + xLen: handleUnaryCall; + xDel: handleUnaryCall; + xTrim: handleUnaryCall; +} + +export interface CacheClient extends Client { + get(request: GetRequest, callback: (error: ServiceError | null, response: GetResponse) => void): ClientUnaryCall; + get( + request: GetRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: GetResponse) => void, + ): ClientUnaryCall; + get( + request: GetRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: GetResponse) => void, + ): ClientUnaryCall; + put(request: PutRequest, callback: (error: ServiceError | null, response: PutResponse) => void): ClientUnaryCall; + put( + request: PutRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: PutResponse) => void, + ): ClientUnaryCall; + put( + request: PutRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: PutResponse) => void, + ): ClientUnaryCall; + putMany( + request: PutManyRequest, + callback: (error: ServiceError | null, response: PutManyResponse) => void, + ): ClientUnaryCall; + putMany( + request: PutManyRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: PutManyResponse) => void, + ): ClientUnaryCall; + putMany( + request: PutManyRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: PutManyResponse) => void, + ): ClientUnaryCall; + delete( + request: DeleteRequest, + callback: (error: ServiceError | null, response: DeleteResponse) => void, + ): ClientUnaryCall; + delete( + request: DeleteRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: DeleteResponse) => void, + ): ClientUnaryCall; + delete( + request: DeleteRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: DeleteResponse) => void, + ): ClientUnaryCall; + deleteMany( + request: DeleteManyRequest, + callback: (error: ServiceError | null, response: DeleteManyResponse) => void, + ): ClientUnaryCall; + deleteMany( + request: DeleteManyRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: DeleteManyResponse) => void, + ): ClientUnaryCall; + deleteMany( + request: DeleteManyRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: DeleteManyResponse) => void, + ): ClientUnaryCall; + bloomAdd( + request: BloomAddRequest, + callback: (error: ServiceError | null, response: BloomAddResponse) => void, + ): ClientUnaryCall; + bloomAdd( + request: BloomAddRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: BloomAddResponse) => void, + ): ClientUnaryCall; + bloomAdd( + request: BloomAddRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: BloomAddResponse) => void, + ): ClientUnaryCall; + bloomTest( + request: BloomTestRequest, + callback: (error: ServiceError | null, response: BloomTestResponse) => void, + ): ClientUnaryCall; + bloomTest( + request: BloomTestRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: BloomTestResponse) => void, + ): ClientUnaryCall; + bloomTest( + request: BloomTestRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: BloomTestResponse) => void, + ): ClientUnaryCall; + setAdd( + request: SetAddRequest, + callback: (error: ServiceError | null, response: SetAddResponse) => void, + ): ClientUnaryCall; + setAdd( + request: SetAddRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: SetAddResponse) => void, + ): ClientUnaryCall; + setAdd( + request: SetAddRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: SetAddResponse) => void, + ): ClientUnaryCall; + setRemove( + request: SetRemoveRequest, + callback: (error: ServiceError | null, response: SetRemoveResponse) => void, + ): ClientUnaryCall; + setRemove( + request: SetRemoveRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: SetRemoveResponse) => void, + ): ClientUnaryCall; + setRemove( + request: SetRemoveRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: SetRemoveResponse) => void, + ): ClientUnaryCall; + setContains( + request: SetContainsRequest, + callback: (error: ServiceError | null, response: SetContainsResponse) => void, + ): ClientUnaryCall; + setContains( + request: SetContainsRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: SetContainsResponse) => void, + ): ClientUnaryCall; + setContains( + request: SetContainsRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: SetContainsResponse) => void, + ): ClientUnaryCall; + setCard( + request: SetCardRequest, + callback: (error: ServiceError | null, response: SetCardResponse) => void, + ): ClientUnaryCall; + setCard( + request: SetCardRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: SetCardResponse) => void, + ): ClientUnaryCall; + setCard( + request: SetCardRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: SetCardResponse) => void, + ): ClientUnaryCall; + setMembers( + request: SetMembersRequest, + callback: (error: ServiceError | null, response: SetMembersResponse) => void, + ): ClientUnaryCall; + setMembers( + request: SetMembersRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: SetMembersResponse) => void, + ): ClientUnaryCall; + setMembers( + request: SetMembersRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: SetMembersResponse) => void, + ): ClientUnaryCall; + zAdd(request: ZAddRequest, callback: (error: ServiceError | null, response: ZAddResponse) => void): ClientUnaryCall; + zAdd( + request: ZAddRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: ZAddResponse) => void, + ): ClientUnaryCall; + zAdd( + request: ZAddRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: ZAddResponse) => void, + ): ClientUnaryCall; + zRem(request: ZRemRequest, callback: (error: ServiceError | null, response: ZRemResponse) => void): ClientUnaryCall; + zRem( + request: ZRemRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: ZRemResponse) => void, + ): ClientUnaryCall; + zRem( + request: ZRemRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: ZRemResponse) => void, + ): ClientUnaryCall; + zScore( + request: ZScoreRequest, + callback: (error: ServiceError | null, response: ZScoreResponse) => void, + ): ClientUnaryCall; + zScore( + request: ZScoreRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: ZScoreResponse) => void, + ): ClientUnaryCall; + zScore( + request: ZScoreRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: ZScoreResponse) => void, + ): ClientUnaryCall; + zCard( + request: ZCardRequest, + callback: (error: ServiceError | null, response: ZCardResponse) => void, + ): ClientUnaryCall; + zCard( + request: ZCardRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: ZCardResponse) => void, + ): ClientUnaryCall; + zCard( + request: ZCardRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: ZCardResponse) => void, + ): ClientUnaryCall; + zRange( + request: ZRangeRequest, + callback: (error: ServiceError | null, response: ZRangeResponse) => void, + ): ClientUnaryCall; + zRange( + request: ZRangeRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: ZRangeResponse) => void, + ): ClientUnaryCall; + zRange( + request: ZRangeRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: ZRangeResponse) => void, + ): ClientUnaryCall; + zRangeByScore( + request: ZRangeByScoreRequest, + callback: (error: ServiceError | null, response: ZRangeResponse) => void, + ): ClientUnaryCall; + zRangeByScore( + request: ZRangeByScoreRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: ZRangeResponse) => void, + ): ClientUnaryCall; + zRangeByScore( + request: ZRangeByScoreRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: ZRangeResponse) => void, + ): ClientUnaryCall; + geoAdd( + request: GeoAddRequest, + callback: (error: ServiceError | null, response: GeoAddResponse) => void, + ): ClientUnaryCall; + geoAdd( + request: GeoAddRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: GeoAddResponse) => void, + ): ClientUnaryCall; + geoAdd( + request: GeoAddRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: GeoAddResponse) => void, + ): ClientUnaryCall; + geoRem( + request: GeoRemRequest, + callback: (error: ServiceError | null, response: GeoRemResponse) => void, + ): ClientUnaryCall; + geoRem( + request: GeoRemRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: GeoRemResponse) => void, + ): ClientUnaryCall; + geoRem( + request: GeoRemRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: GeoRemResponse) => void, + ): ClientUnaryCall; + geoPos( + request: GeoPosRequest, + callback: (error: ServiceError | null, response: GeoPosResponse) => void, + ): ClientUnaryCall; + geoPos( + request: GeoPosRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: GeoPosResponse) => void, + ): ClientUnaryCall; + geoPos( + request: GeoPosRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: GeoPosResponse) => void, + ): ClientUnaryCall; + geoCard( + request: GeoCardRequest, + callback: (error: ServiceError | null, response: GeoCardResponse) => void, + ): ClientUnaryCall; + geoCard( + request: GeoCardRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: GeoCardResponse) => void, + ): ClientUnaryCall; + geoCard( + request: GeoCardRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: GeoCardResponse) => void, + ): ClientUnaryCall; + geoDist( + request: GeoDistRequest, + callback: (error: ServiceError | null, response: GeoDistResponse) => void, + ): ClientUnaryCall; + geoDist( + request: GeoDistRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: GeoDistResponse) => void, + ): ClientUnaryCall; + geoDist( + request: GeoDistRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: GeoDistResponse) => void, + ): ClientUnaryCall; + geoRadius( + request: GeoRadiusRequest, + callback: (error: ServiceError | null, response: GeoRadiusResponse) => void, + ): ClientUnaryCall; + geoRadius( + request: GeoRadiusRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: GeoRadiusResponse) => void, + ): ClientUnaryCall; + geoRadius( + request: GeoRadiusRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: GeoRadiusResponse) => void, + ): ClientUnaryCall; + lPush( + request: LPushRequest, + callback: (error: ServiceError | null, response: LPushResponse) => void, + ): ClientUnaryCall; + lPush( + request: LPushRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: LPushResponse) => void, + ): ClientUnaryCall; + lPush( + request: LPushRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: LPushResponse) => void, + ): ClientUnaryCall; + rPush( + request: RPushRequest, + callback: (error: ServiceError | null, response: RPushResponse) => void, + ): ClientUnaryCall; + rPush( + request: RPushRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: RPushResponse) => void, + ): ClientUnaryCall; + rPush( + request: RPushRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: RPushResponse) => void, + ): ClientUnaryCall; + lPop(request: LPopRequest, callback: (error: ServiceError | null, response: LPopResponse) => void): ClientUnaryCall; + lPop( + request: LPopRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: LPopResponse) => void, + ): ClientUnaryCall; + lPop( + request: LPopRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: LPopResponse) => void, + ): ClientUnaryCall; + rPop(request: RPopRequest, callback: (error: ServiceError | null, response: RPopResponse) => void): ClientUnaryCall; + rPop( + request: RPopRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: RPopResponse) => void, + ): ClientUnaryCall; + rPop( + request: RPopRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: RPopResponse) => void, + ): ClientUnaryCall; + lLen(request: LLenRequest, callback: (error: ServiceError | null, response: LLenResponse) => void): ClientUnaryCall; + lLen( + request: LLenRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: LLenResponse) => void, + ): ClientUnaryCall; + lLen( + request: LLenRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: LLenResponse) => void, + ): ClientUnaryCall; + lIndex( + request: LIndexRequest, + callback: (error: ServiceError | null, response: LIndexResponse) => void, + ): ClientUnaryCall; + lIndex( + request: LIndexRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: LIndexResponse) => void, + ): ClientUnaryCall; + lIndex( + request: LIndexRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: LIndexResponse) => void, + ): ClientUnaryCall; + lRange( + request: LRangeRequest, + callback: (error: ServiceError | null, response: LRangeResponse) => void, + ): ClientUnaryCall; + lRange( + request: LRangeRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: LRangeResponse) => void, + ): ClientUnaryCall; + lRange( + request: LRangeRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: LRangeResponse) => void, + ): ClientUnaryCall; + hSet(request: HSetRequest, callback: (error: ServiceError | null, response: HSetResponse) => void): ClientUnaryCall; + hSet( + request: HSetRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: HSetResponse) => void, + ): ClientUnaryCall; + hSet( + request: HSetRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: HSetResponse) => void, + ): ClientUnaryCall; + hGet(request: HGetRequest, callback: (error: ServiceError | null, response: HGetResponse) => void): ClientUnaryCall; + hGet( + request: HGetRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: HGetResponse) => void, + ): ClientUnaryCall; + hGet( + request: HGetRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: HGetResponse) => void, + ): ClientUnaryCall; + hDel(request: HDelRequest, callback: (error: ServiceError | null, response: HDelResponse) => void): ClientUnaryCall; + hDel( + request: HDelRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: HDelResponse) => void, + ): ClientUnaryCall; + hDel( + request: HDelRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: HDelResponse) => void, + ): ClientUnaryCall; + hExists( + request: HExistsRequest, + callback: (error: ServiceError | null, response: HExistsResponse) => void, + ): ClientUnaryCall; + hExists( + request: HExistsRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: HExistsResponse) => void, + ): ClientUnaryCall; + hExists( + request: HExistsRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: HExistsResponse) => void, + ): ClientUnaryCall; + hLen(request: HLenRequest, callback: (error: ServiceError | null, response: HLenResponse) => void): ClientUnaryCall; + hLen( + request: HLenRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: HLenResponse) => void, + ): ClientUnaryCall; + hLen( + request: HLenRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: HLenResponse) => void, + ): ClientUnaryCall; + hGetAll( + request: HGetAllRequest, + callback: (error: ServiceError | null, response: HGetAllResponse) => void, + ): ClientUnaryCall; + hGetAll( + request: HGetAllRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: HGetAllResponse) => void, + ): ClientUnaryCall; + hGetAll( + request: HGetAllRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: HGetAllResponse) => void, + ): ClientUnaryCall; + incr(request: IncrRequest, callback: (error: ServiceError | null, response: IncrResponse) => void): ClientUnaryCall; + incr( + request: IncrRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: IncrResponse) => void, + ): ClientUnaryCall; + incr( + request: IncrRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: IncrResponse) => void, + ): ClientUnaryCall; + counterGet( + request: CounterGetRequest, + callback: (error: ServiceError | null, response: CounterGetResponse) => void, + ): ClientUnaryCall; + counterGet( + request: CounterGetRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: CounterGetResponse) => void, + ): ClientUnaryCall; + counterGet( + request: CounterGetRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: CounterGetResponse) => void, + ): ClientUnaryCall; + jsonSet( + request: JsonSetRequest, + callback: (error: ServiceError | null, response: JsonSetResponse) => void, + ): ClientUnaryCall; + jsonSet( + request: JsonSetRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: JsonSetResponse) => void, + ): ClientUnaryCall; + jsonSet( + request: JsonSetRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: JsonSetResponse) => void, + ): ClientUnaryCall; + jsonGet( + request: JsonGetRequest, + callback: (error: ServiceError | null, response: JsonGetResponse) => void, + ): ClientUnaryCall; + jsonGet( + request: JsonGetRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: JsonGetResponse) => void, + ): ClientUnaryCall; + jsonGet( + request: JsonGetRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: JsonGetResponse) => void, + ): ClientUnaryCall; + jsonDel( + request: JsonDelRequest, + callback: (error: ServiceError | null, response: JsonDelResponse) => void, + ): ClientUnaryCall; + jsonDel( + request: JsonDelRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: JsonDelResponse) => void, + ): ClientUnaryCall; + jsonDel( + request: JsonDelRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: JsonDelResponse) => void, + ): ClientUnaryCall; + bitSet( + request: BitSetRequest, + callback: (error: ServiceError | null, response: BitSetResponse) => void, + ): ClientUnaryCall; + bitSet( + request: BitSetRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: BitSetResponse) => void, + ): ClientUnaryCall; + bitSet( + request: BitSetRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: BitSetResponse) => void, + ): ClientUnaryCall; + bitGet( + request: BitGetRequest, + callback: (error: ServiceError | null, response: BitGetResponse) => void, + ): ClientUnaryCall; + bitGet( + request: BitGetRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: BitGetResponse) => void, + ): ClientUnaryCall; + bitGet( + request: BitGetRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: BitGetResponse) => void, + ): ClientUnaryCall; + bitCount( + request: BitCountRequest, + callback: (error: ServiceError | null, response: BitCountResponse) => void, + ): ClientUnaryCall; + bitCount( + request: BitCountRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: BitCountResponse) => void, + ): ClientUnaryCall; + bitCount( + request: BitCountRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: BitCountResponse) => void, + ): ClientUnaryCall; + bitPos( + request: BitPosRequest, + callback: (error: ServiceError | null, response: BitPosResponse) => void, + ): ClientUnaryCall; + bitPos( + request: BitPosRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: BitPosResponse) => void, + ): ClientUnaryCall; + bitPos( + request: BitPosRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: BitPosResponse) => void, + ): ClientUnaryCall; + hllAdd( + request: HLLAddRequest, + callback: (error: ServiceError | null, response: HLLAddResponse) => void, + ): ClientUnaryCall; + hllAdd( + request: HLLAddRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: HLLAddResponse) => void, + ): ClientUnaryCall; + hllAdd( + request: HLLAddRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: HLLAddResponse) => void, + ): ClientUnaryCall; + hllCount( + request: HLLCountRequest, + callback: (error: ServiceError | null, response: HLLCountResponse) => void, + ): ClientUnaryCall; + hllCount( + request: HLLCountRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: HLLCountResponse) => void, + ): ClientUnaryCall; + hllCount( + request: HLLCountRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: HLLCountResponse) => void, + ): ClientUnaryCall; + topKAdd( + request: TopKAddRequest, + callback: (error: ServiceError | null, response: TopKAddResponse) => void, + ): ClientUnaryCall; + topKAdd( + request: TopKAddRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: TopKAddResponse) => void, + ): ClientUnaryCall; + topKAdd( + request: TopKAddRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: TopKAddResponse) => void, + ): ClientUnaryCall; + topKList( + request: TopKListRequest, + callback: (error: ServiceError | null, response: TopKListResponse) => void, + ): ClientUnaryCall; + topKList( + request: TopKListRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: TopKListResponse) => void, + ): ClientUnaryCall; + topKList( + request: TopKListRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: TopKListResponse) => void, + ): ClientUnaryCall; + cmsIncr( + request: CMSIncrRequest, + callback: (error: ServiceError | null, response: CMSIncrResponse) => void, + ): ClientUnaryCall; + cmsIncr( + request: CMSIncrRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: CMSIncrResponse) => void, + ): ClientUnaryCall; + cmsIncr( + request: CMSIncrRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: CMSIncrResponse) => void, + ): ClientUnaryCall; + cmsQuery( + request: CMSQueryRequest, + callback: (error: ServiceError | null, response: CMSQueryResponse) => void, + ): ClientUnaryCall; + cmsQuery( + request: CMSQueryRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: CMSQueryResponse) => void, + ): ClientUnaryCall; + cmsQuery( + request: CMSQueryRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: CMSQueryResponse) => void, + ): ClientUnaryCall; + vAdd(request: VAddRequest, callback: (error: ServiceError | null, response: VAddResponse) => void): ClientUnaryCall; + vAdd( + request: VAddRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: VAddResponse) => void, + ): ClientUnaryCall; + vAdd( + request: VAddRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: VAddResponse) => void, + ): ClientUnaryCall; + vRem(request: VRemRequest, callback: (error: ServiceError | null, response: VRemResponse) => void): ClientUnaryCall; + vRem( + request: VRemRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: VRemResponse) => void, + ): ClientUnaryCall; + vRem( + request: VRemRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: VRemResponse) => void, + ): ClientUnaryCall; + vSim(request: VSimRequest, callback: (error: ServiceError | null, response: VSimResponse) => void): ClientUnaryCall; + vSim( + request: VSimRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: VSimResponse) => void, + ): ClientUnaryCall; + vSim( + request: VSimRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: VSimResponse) => void, + ): ClientUnaryCall; + vCard( + request: VCardRequest, + callback: (error: ServiceError | null, response: VCardResponse) => void, + ): ClientUnaryCall; + vCard( + request: VCardRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: VCardResponse) => void, + ): ClientUnaryCall; + vCard( + request: VCardRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: VCardResponse) => void, + ): ClientUnaryCall; + vDim(request: VDimRequest, callback: (error: ServiceError | null, response: VDimResponse) => void): ClientUnaryCall; + vDim( + request: VDimRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: VDimResponse) => void, + ): ClientUnaryCall; + vDim( + request: VDimRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: VDimResponse) => void, + ): ClientUnaryCall; + vEmb(request: VEmbRequest, callback: (error: ServiceError | null, response: VEmbResponse) => void): ClientUnaryCall; + vEmb( + request: VEmbRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: VEmbResponse) => void, + ): ClientUnaryCall; + vEmb( + request: VEmbRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: VEmbResponse) => void, + ): ClientUnaryCall; + xAdd(request: XAddRequest, callback: (error: ServiceError | null, response: XAddResponse) => void): ClientUnaryCall; + xAdd( + request: XAddRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: XAddResponse) => void, + ): ClientUnaryCall; + xAdd( + request: XAddRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: XAddResponse) => void, + ): ClientUnaryCall; + xRange( + request: XRangeRequest, + callback: (error: ServiceError | null, response: XRangeResponse) => void, + ): ClientUnaryCall; + xRange( + request: XRangeRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: XRangeResponse) => void, + ): ClientUnaryCall; + xRange( + request: XRangeRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: XRangeResponse) => void, + ): ClientUnaryCall; + xRevRange( + request: XRevRangeRequest, + callback: (error: ServiceError | null, response: XRangeResponse) => void, + ): ClientUnaryCall; + xRevRange( + request: XRevRangeRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: XRangeResponse) => void, + ): ClientUnaryCall; + xRevRange( + request: XRevRangeRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: XRangeResponse) => void, + ): ClientUnaryCall; + xLen(request: XLenRequest, callback: (error: ServiceError | null, response: XLenResponse) => void): ClientUnaryCall; + xLen( + request: XLenRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: XLenResponse) => void, + ): ClientUnaryCall; + xLen( + request: XLenRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: XLenResponse) => void, + ): ClientUnaryCall; + xDel(request: XDelRequest, callback: (error: ServiceError | null, response: XDelResponse) => void): ClientUnaryCall; + xDel( + request: XDelRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: XDelResponse) => void, + ): ClientUnaryCall; + xDel( + request: XDelRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: XDelResponse) => void, + ): ClientUnaryCall; + xTrim( + request: XTrimRequest, + callback: (error: ServiceError | null, response: XTrimResponse) => void, + ): ClientUnaryCall; + xTrim( + request: XTrimRequest, + metadata: Metadata, + callback: (error: ServiceError | null, response: XTrimResponse) => void, + ): ClientUnaryCall; + xTrim( + request: XTrimRequest, + metadata: Metadata, + options: Partial, + callback: (error: ServiceError | null, response: XTrimResponse) => void, + ): ClientUnaryCall; +} + +export const CacheClient = makeGenericClientConstructor(CacheService, "supercache.cache.v1.Cache") as unknown as { + new (address: string, credentials: ChannelCredentials, options?: Partial): CacheClient; + service: typeof CacheService; + serviceName: string; +}; + +function bytesFromBase64(b64: string): Uint8Array { + return Uint8Array.from(globalThis.Buffer.from(b64, "base64")); +} + +function base64FromBytes(arr: Uint8Array): string { + return globalThis.Buffer.from(arr).toString("base64"); +} + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; + +export type DeepPartial = T extends Builtin ? T + : T extends globalThis.Array ? globalThis.Array> + : T extends ReadonlyArray ? ReadonlyArray> + : T extends {} ? { [K in keyof T]?: DeepPartial } + : Partial; + +function longToNumber(int64: { toString(): string }): number { + const num = globalThis.Number(int64.toString()); + if (num > globalThis.Number.MAX_SAFE_INTEGER) { + throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER"); + } + if (num < globalThis.Number.MIN_SAFE_INTEGER) { + throw new globalThis.Error("Value is smaller than Number.MIN_SAFE_INTEGER"); + } + return num; +} + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} + +export interface MessageFns { + encode(message: T, writer?: BinaryWriter): BinaryWriter; + decode(input: BinaryReader | Uint8Array, length?: number): T; + fromJSON(object: any): T; + toJSON(message: T): unknown; + create(base?: DeepPartial): T; + fromPartial(object: DeepPartial): T; +} diff --git a/clients/node/src/index.ts b/clients/node/src/index.ts new file mode 100644 index 0000000..654f1c1 --- /dev/null +++ b/clients/node/src/index.ts @@ -0,0 +1,27 @@ +export { Client, clientMethods, dial, dialTls } from "./client.js"; +export type { CacheApi } from "./client.js"; +export type { + BitPos, + BitValue, + Bytes, + GeoMember, + HashField, + Present, + PutOptions, + StreamEntry, + TlsOptions, + TopKEntry, + TopKResult, + VSimHit, + ZMember, +} from "./types.js"; +export { + KeyErrorItem, + KeyErrors, + NotFound, + PeerFailure, + PeerFailures, + StatusError, + isTransport, +} from "./errors.js"; +export { Session, type SessionOptions } from "./session.js"; diff --git a/clients/node/src/session.ts b/clients/node/src/session.ts new file mode 100644 index 0000000..99b284f --- /dev/null +++ b/clients/node/src/session.ts @@ -0,0 +1,127 @@ +/** Sticky multi-seed dialing, same policy as cmd/sc. */ + +import { Client, clientMethods, dial, dialTls, type CacheApi } from "./client.js"; +import type { TlsOptions } from "./types.js"; +import { StatusError, isTransport } from "./errors.js"; + +export interface SessionOptions { + tls?: TlsOptions; + timeoutMs?: number; + /** How long to wait for a seed to accept a connection. Default 500ms. */ + probeMs?: number; +} + +/** + * Walk seeds on dial. Retry a call once after UNAVAILABLE or a reset connection. + * A call-level deadline is not retried: the server may already have applied it. + */ +export class Session { + private readonly addrs: string[]; + private readonly tls?: TlsOptions; + private readonly timeoutMs?: number; + private readonly probeMs: number; + private idx = 0; + private current: Client | undefined; + private addr: string | undefined; + private chain: Promise = Promise.resolve(); + + constructor(addrs: readonly string[], opts: SessionOptions = {}) { + if (addrs.length === 0) throw new TypeError("at least one address is required"); + this.addrs = [...addrs]; + this.tls = opts.tls; + this.timeoutMs = opts.timeoutMs; + this.probeMs = opts.probeMs ?? 500; + for (const name of clientMethods) { + (this as unknown as Record Promise>)[name] = (...args: unknown[]) => + this.run((client) => (client[name] as (...a: unknown[]) => Promise)(...args)); + } + } + + connectedAddr(): string | undefined { + return this.addr; + } + + close(): void { + this.current?.close(); + this.current = undefined; + this.addr = undefined; + } + + async run(fn: (client: Client) => Promise): Promise { + const cli = await this.ensure(); + try { + return await fn(cli); + } catch (err) { + if (!isTransport(err)) throw err; + const first = err; + await this.invalidate(); + let next: Client; + try { + next = await this.ensure(); + } catch (err2) { + throw new StatusError("UNAVAILABLE", `${messageOf(first)} (re-dial: ${messageOf(err2)})`); + } + return fn(next); + } + } + + private dial(addr: string): Client { + if (!this.tls) return dial(addr, this.timeoutMs); + return dialTls(addr, this.tls, this.timeoutMs); + } + + private async ensure(): Promise { + return this.exclusive(async () => { + if (this.current) return this.current; + const errors: string[] = []; + const n = this.addrs.length; + for (let i = 0; i < n; i++) { + const idx = (this.idx + i) % n; + const addr = this.addrs[idx]!; + let cli: Client | undefined; + try { + cli = this.dial(addr); + await cli.ready(this.probeMs); + } catch (err) { + errors.push(`${addr}: ${messageOf(err)}`); + cli?.close(); + continue; + } + this.current = cli; + this.idx = idx; + this.addr = addr; + return cli; + } + throw new StatusError("UNAVAILABLE", `all cache seeds failed:\n ${errors.join("\n ")}`); + }); + } + + private async invalidate(): Promise { + return this.exclusive(async () => { + this.current?.close(); + this.current = undefined; + this.idx = (this.idx + 1) % this.addrs.length; + this.addr = undefined; + }); + } + + private async exclusive(fn: () => Promise): Promise { + const prev = this.chain; + let release: () => void = () => {}; + this.chain = new Promise((resolve) => { + release = resolve; + }); + await prev; + try { + return await fn(); + } finally { + release(); + } + } +} + +function messageOf(err: unknown): string { + return err instanceof Error ? err.message : String(err); +} + +export interface Session extends CacheApi {} diff --git a/clients/node/src/types.ts b/clients/node/src/types.ts new file mode 100644 index 0000000..d01c01a --- /dev/null +++ b/clients/node/src/types.ts @@ -0,0 +1,69 @@ +/** Values returned by Client. These are not the generated wire messages. */ + +export type Bytes = Uint8Array | string; + +export interface ZMember { + member: Uint8Array; + score: number; +} + +export interface GeoMember { + member: Uint8Array; + lon: number; + lat: number; + dist: number; +} + +export interface HashField { + field: Uint8Array; + value: Uint8Array; +} + +export interface StreamEntry { + id: string; + payload: Uint8Array; +} + +export interface VSimHit { + member: Uint8Array; + score: number; +} + +export interface TopKEntry { + item: Uint8Array; + count: number; +} + +/** A read that distinguishes a missing structure from a real zero. */ +export interface Present { + value: number; + found: boolean; +} + +export interface TopKResult { + entries: TopKEntry[]; + found: boolean; +} + +export interface BitValue { + value: boolean; + found: boolean; +} + +export interface BitPos { + pos: number; + found: boolean; +} + +/** Undefined ttlMs leaves ttl_set false. 0 sets ttl_set and stores no expiry. */ +export interface PutOptions { + ttlMs?: number; + timeoutMs?: number; +} + +export interface TlsOptions { + caFile: string; + serverName: string; + clientCert?: string; + clientKey?: string; +} diff --git a/clients/node/test/client.test.ts b/clients/node/test/client.test.ts new file mode 100644 index 0000000..ffe234f --- /dev/null +++ b/clients/node/test/client.test.ts @@ -0,0 +1,361 @@ +import { spawn, type ChildProcess } from "node:child_process"; +import { existsSync } from "node:fs"; +import { createInterface } from "node:readline"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { after, before, test } from "node:test"; +import assert from "node:assert/strict"; +import { randomUUID } from "node:crypto"; + +import * as grpc from "@grpc/grpc-js"; + +import { CacheService, GetResponse } from "../src/gen/cache.js"; +import { dial, dialTls, KeyErrors, NotFound, Session, StatusError, type Client } from "../src/index.js"; + +function repoRoot(): string { + let dir = path.dirname(fileURLToPath(import.meta.url)); + for (let i = 0; i < 8; i++) { + if (existsSync(path.join(dir, "go.mod"))) return dir; + dir = path.dirname(dir); + } + throw new Error("go.mod not found"); +} + +interface Proc { + proc: ChildProcess; + meta: Record; +} + +function nid(): string { + return randomUUID().replace(/-/g, "").slice(0, 12); +} + +function text(value: Uint8Array): string { + return Buffer.from(value).toString("utf8"); +} + +function start(binary: string, args: string[] = []): Promise { + const proc = spawn(binary, args, { stdio: ["ignore", "pipe", "pipe"] }); + const meta: Record = {}; + const need = args.includes("-tls") || args.includes("-mtls") ? "client_key" : "addr"; + return new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error(`conformance timeout waiting for ${need}`)), 20_000); + const rl = createInterface({ input: proc.stdout! }); + rl.on("line", (line) => { + const eq = line.indexOf("="); + if (eq < 0) return; + meta[line.slice(0, eq)] = line.slice(eq + 1); + if (meta[need]) { + clearTimeout(timer); + resolve({ proc, meta }); + } + }); + proc.once("exit", (code) => { + clearTimeout(timer); + reject(new Error(`conformance exited ${code} before ${need}`)); + }); + }); +} + +function stop(proc: Proc | undefined): Promise { + if (!proc || proc.proc.exitCode != null) return Promise.resolve(); + return new Promise((resolve) => { + proc.proc.once("exit", () => resolve()); + proc.proc.kill("SIGTERM"); + }); +} + +let plain: Proc; +let tls: Proc; +let mtls: Proc; +let client: Client; + +before(async () => { + const root = repoRoot(); + const binary = path.join(root, "clients", "node", "dist", "conformance"); + await new Promise((resolve, reject) => { + const build = spawn("go", ["build", "-o", binary, "./clients/conformance"], { cwd: root, stdio: "inherit" }); + build.on("exit", (code) => (code === 0 ? resolve() : reject(new Error(`go build exited ${code}`)))); + }); + plain = await start(binary); + tls = await start(binary, ["-tls"]); + mtls = await start(binary, ["-mtls"]); + client = dial(plain.meta.addr!); +}); + +after(async () => { + client?.close(); + await stop(plain); + await stop(tls); + await stop(mtls); +}); + +test("get put delete and NotFound", async () => { + const key = "k-" + nid(); + await assert.rejects(() => client.get("cacheonly", key), NotFound); + await client.put("cacheonly", key, "v"); + assert.equal(text(await client.get("cacheonly", key)), "v"); + await client.delete("cacheonly", key); + await assert.rejects(() => client.get("cacheonly", key), NotFound); +}); + +test("ttl omitted and zero", async () => { + const a = "ttl-a-" + nid(); + const b = "ttl-b-" + nid(); + await client.put("cacheonly", a, "a"); + await client.put("cacheonly", b, "b", { ttlMs: 0 }); + assert.equal(text(await client.get("cacheonly", a)), "a"); + assert.equal(text(await client.get("cacheonly", b)), "b"); +}); + +test("putMany and empty key", async () => { + const a = "m-" + nid(); + const b = "n-" + nid(); + await client.putMany("cacheonly", [ + { key: a, value: "1" }, + { key: b, value: "2" }, + ]); + assert.equal(text(await client.get("cacheonly", a)), "1"); + await client.deleteMany("cacheonly", [a, b]); + await assert.rejects(() => client.get("cacheonly", a), NotFound); + await assert.rejects( + () => + client.putMany("cacheonly", [ + { key: "", value: "x" }, + { key: "", value: "y" }, + ]), + (err: unknown) => { + assert.ok(err instanceof KeyErrors); + assert.ok(err.errors.every((item) => item.key === "")); + return true; + }, + ); +}); + +test("missing keyspace is status NOT_FOUND", async () => { + await assert.rejects(() => client.get("nope", "k"), (err: unknown) => { + assert.ok(err instanceof StatusError); + assert.equal(err.code, "NOT_FOUND"); + assert.ok(!(err instanceof NotFound)); + return true; + }); + await assert.rejects(() => client.put("nope", "k", "v"), (err: unknown) => { + assert.ok(err instanceof StatusError); + assert.equal(err.code, "NOT_FOUND"); + return true; + }); +}); + +test("loadthrough and wrong mode", async () => { + assert.equal(text(await client.get("loadthrough", "seeded")), "from-source"); + await assert.rejects(() => client.get("loadthrough", "missing"), NotFound); + await assert.rejects(() => client.get("set", "anything"), (err: unknown) => { + assert.ok(err instanceof StatusError); + assert.equal(err.code, "INVALID_ARGUMENT"); + return true; + }); +}); + +test("structures", async () => { + const name = nid(); + assert.equal(await client.bloomTest("bloom", name, "ghost"), false); + await client.bloomAdd("bloom", name, "alice"); + assert.equal(await client.bloomTest("bloom", name, "alice"), true); + + await client.setAdd("set", name, "x"); + assert.equal(await client.setContains("set", name, "x"), true); + assert.equal(await client.setCard("set", name), 1); + assert.ok((await client.setMembers("set", name)).some((m) => text(m) === "x")); + await client.setRemove("set", name, "x"); + assert.equal(await client.setContains("set", name, "x"), false); + + await client.zAdd("zset", name, "alice", 10); + await client.zAdd("zset", name, "bob", 20); + assert.equal(await client.zScore("zset", name, "alice"), 10); + assert.equal(await client.zCard("zset", name), 2); + assert.deepEqual( + (await client.zRange("zset", name, 0, -1)).map((m) => text(m.member)), + ["alice", "bob"], + ); + assert.deepEqual( + (await client.zRangeByScore("zset", name, 10, 10)).map((m) => text(m.member)), + ["alice"], + ); + await client.zRem("zset", name, "bob"); + assert.equal(await client.zScore("zset", name, "bob"), null); + + await client.geoAdd("geo", name, "a", -74, 40.7); + await client.geoAdd("geo", name, "b", -74.1, 40.8); + assert.deepEqual(await client.geoPos("geo", name, "a"), [-74, 40.7]); + const dist = await client.geoDist("geo", name, "a", "b"); + assert.ok(dist != null && dist > 0); + assert.equal(await client.geoCard("geo", name), 2); + const hits = await client.geoRadius("geo", name, -74, 40.7, 50_000, 10); + assert.ok(hits.some((h) => text(h.member) === "a")); + await client.geoRem("geo", name, "b"); + assert.equal(await client.geoPos("geo", name, "b"), null); + + await client.lPush("list", name, "b"); + await client.lPush("list", name, "a"); + await client.rPush("list", name, "c"); + assert.equal(await client.lLen("list", name), 3); + assert.equal(text((await client.lIndex("list", name, 0))!), "a"); + assert.deepEqual( + (await client.lRange("list", name, 0, -1)).map((item) => text(item)), + ["a", "b", "c"], + ); + assert.equal(text((await client.lPop("list", name))!), "a"); + assert.equal(text((await client.rPop("list", name))!), "c"); + + await client.hSet("hash", name, "email", "a@b"); + assert.equal(text((await client.hGet("hash", name, "email"))!), "a@b"); + assert.equal(await client.hExists("hash", name, "email"), true); + assert.equal(await client.hLen("hash", name), 1); + assert.equal(text((await client.hGetAll("hash", name))[0]!.field), "email"); + await client.hDel("hash", name, "email"); + assert.equal(await client.hGet("hash", name, "email"), null); + + assert.equal(await client.incr("counter", name, 2), 2); + assert.equal(await client.incr("counter", name, 3), 5); + const counter = await client.counterGet("counter", name); + assert.equal(counter.found, true); + assert.equal(counter.value, 5); + + await client.jsonSet("json", name, "$.name", '"Ada"'); + assert.equal(text((await client.jsonGet("json", name, "$.name"))!), '"Ada"'); + await client.jsonDel("json", name, "$.name"); + assert.equal(await client.jsonGet("json", name, "$.name"), null); + + await client.bitSet("bitmap", name, 0, true); + const bit = await client.bitGet("bitmap", name, 0); + assert.equal(bit.found, true); + assert.equal(bit.value, true); + assert.ok((await client.bitCount("bitmap", name, 0, -1)) >= 1); + const pos = await client.bitPos("bitmap", name, true, 0, -1); + assert.equal(pos.found, true); + assert.equal(pos.pos, 0); + + await client.hllAdd("hll", name, "alice"); + const hll = await client.hllCount("hll", name); + assert.equal(hll.found, true); + assert.ok(hll.value >= 1); + + await client.topKAdd("topk", name, "t001"); + await client.topKAdd("topk", name, "t001"); + const top = await client.topKList("topk", name); + assert.equal(top.found, true); + assert.ok(top.entries.some((e) => text(e.item) === "t001")); + + await client.cmsIncr("cms", name, "t003", 4); + const cms = await client.cmsQuery("cms", name, "t003"); + assert.equal(cms.found, true); + assert.ok(cms.value >= 4); + + await client.vAdd("vectorset", name, "east", [1, 0, 0, 0]); + const dim = await client.vDim("vectorset", name); + assert.equal(dim.found, true); + assert.equal(dim.value, 4); + const card = await client.vCard("vectorset", name); + assert.equal(card.found, true); + assert.equal(card.value, 1); + const emb = await client.vEmb("vectorset", name, "east"); + assert.ok(emb && emb.length === 4); + const sim = await client.vSim("vectorset", name, [1, 0, 0, 0], 1); + assert.equal(text(sim[0]!.member), "east"); + await client.vRem("vectorset", name, "east"); + + const sid = await client.xAdd("stream", name, "hello"); + assert.ok(sid); + const length = await client.xLen("stream", name); + assert.equal(length.found, true); + assert.ok(length.value >= 1); + const rows = await client.xRange("stream", name, "-", "+", 10); + assert.equal(text(rows[0]!.payload), "hello"); + const rev = await client.xRevRange("stream", name, "-", "+", 10); + assert.equal(rev[0]!.id, sid); + await client.xDel("stream", name, sid); + await client.xTrim("stream", name, 1); +}); + +test("tls and mtls", async () => { + const key = "tls-" + nid(); + const secure = dialTls(tls.meta.addr!, { + caFile: tls.meta.ca!, + serverName: "localhost", + }); + try { + await secure.put("cacheonly", key, "secret"); + assert.equal(text(await secure.get("cacheonly", key)), "secret"); + } finally { + secure.close(); + } + assert.throws(() => dialTls(tls.meta.addr!, { caFile: tls.meta.ca!, serverName: "" }), TypeError); + + const mutual = dialTls(mtls.meta.addr!, { + caFile: mtls.meta.ca!, + serverName: "localhost", + clientCert: mtls.meta.client_cert, + clientKey: mtls.meta.client_key, + }); + try { + const mkey = "mtls-" + nid(); + await mutual.put("cacheonly", mkey, "m"); + assert.equal(text(await mutual.get("cacheonly", mkey)), "m"); + } finally { + mutual.close(); + } + + const bare = dialTls(mtls.meta.addr!, { caFile: mtls.meta.ca!, serverName: "localhost" }); + try { + await assert.rejects(() => bare.put("cacheonly", "nope", "x"), StatusError); + } finally { + bare.close(); + } +}); + +test("session skips a closed port", async () => { + const live = plain.meta.addr!; + const session = new Session(["127.0.0.1:1", live], { timeoutMs: 2000 }); + try { + await assert.rejects(() => session.get("cacheonly", "missing-" + nid()), NotFound); + assert.equal(session.connectedAddr(), live); + } finally { + session.close(); + } +}); + +test("session retries UNAVAILABLE once and does not retry NotFound", async () => { + let gets = 0; + const server = new grpc.Server(); + server.addService(CacheService, { + get: (call: { request: { key: string } }, cb: (err: grpc.ServiceError | null, res: GetResponse | null) => void) => { + gets++; + if (call.request.key === "flaky" && gets === 1) { + cb({ code: grpc.status.UNAVAILABLE, details: "down" } as grpc.ServiceError, null); + return; + } + if (call.request.key === "miss") { + cb(null, GetResponse.create({ found: false, value: Buffer.alloc(0) })); + return; + } + cb(null, GetResponse.create({ found: true, value: Buffer.from("ok") })); + }, + } as never); + const port = await new Promise((resolve, reject) => { + server.bindAsync("127.0.0.1:0", grpc.ServerCredentials.createInsecure(), (err, bound) => { + if (err) reject(err); + else resolve(bound); + }); + }); + const session = new Session([`127.0.0.1:${port}`]); + try { + assert.equal(text(await session.get("cacheonly", "flaky")), "ok"); + assert.equal(gets, 2); + const before = gets; + await assert.rejects(() => session.get("cacheonly", "miss"), NotFound); + assert.equal(gets, before + 1); + } finally { + session.close(); + server.forceShutdown(); + } +}); diff --git a/clients/node/tsconfig.json b/clients/node/tsconfig.json new file mode 100644 index 0000000..5f754f6 --- /dev/null +++ b/clients/node/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "Node16", + "moduleResolution": "Node16", + "outDir": "dist", + "rootDir": ".", + "declaration": true, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "sourceMap": false + }, + "include": ["src/**/*.ts", "test/**/*.ts"] +} diff --git a/clients/python/README.md b/clients/python/README.md new file mode 100644 index 0000000..5a0ff02 --- /dev/null +++ b/clients/python/README.md @@ -0,0 +1,60 @@ +# supercache (Python) + +Sync client for the SuperCache **cache** gRPC port. Python 3.11+. This package is not published to PyPI. + +Do not dial the peer port. + +```bash +python3 -m venv .venv && . .venv/bin/activate +pip install -e ./clients/python +``` + +```python +from datetime import timedelta + +import supercache + +c = supercache.dial("127.0.0.1:9000") +c.put("cacheonly", "greeting", b"hello") # ttl omitted: server keyspace TTL +c.put("cacheonly", "forever", b"x", ttl=timedelta(0)) # ttl_set, no expiry +print(c.get("cacheonly", "greeting")) +c.close() +``` + +TLS: + +```python +c = supercache.dial_tls("127.0.0.1:9000", "ca.pem", "cache.example", "client.pem", "client-key.pem") +``` + +`server_name` is required. Pass both client files or neither. + +## Errors + +| Exception | When | +|-----------|------| +| `NotFound` | `get` returned `found=false` | +| `StatusError` | gRPC status. `.code` is `NOT_FOUND`, `INVALID_ARGUMENT`, `UNAVAILABLE`, … | +| `KeyErrors` | `put_many` / `delete_many` body listed per-key failures | +| `PeerFailures` | `delete` body listed replica failures | + +A missing keyspace is `StatusError` with code `NOT_FOUND`, not `NotFound`. + +## Session + +`Session` keeps a sticky seed list. It walks the list on dial. After `UNAVAILABLE` or a connection reset/refused/broken pipe it drops the channel, advances one seed, and retries the call once. It does not retry `NotFound`, `INVALID_ARGUMENT`, batch errors, or a call deadline. + +```python +from datetime import timedelta + +with supercache.Session(["127.0.0.1:9000", "127.0.0.1:9010"], timeout=timedelta(seconds=5)) as s: + s.put("cacheonly", "k", b"v") +``` + +There is no default per-call deadline. `Session(..., timeout=...)` or a method's `timeout=` sets one. `sc` uses 5s; this library does not. + +## Methods + +Names follow `pkg/client` in snake_case. Redis-style commands stay one word (`zadd`, `lpush`, `hget`, `xrevrange`). The full map is `SURFACE` in `scripts/check-client-surface.py`. Values, items, members, and payloads are `bytes`. Hash fields are `str` or `bytes`. A vector is a sequence of floats, not a string. + +`bloom_test` / `set_contains` / `hexists` return false when the entry is absent. `hget`, `lpop`, `rpop`, `lindex`, `json_get`, and `vemb` return `None`. `bit_get` returns `BitValue(value, found)`. Counts that can be absent (`counter_get`, `hll_count`, `cms_query`, `vcard`, `vdim`, `xlen`) return `Present(value, found)`. `topk_list` returns `TopKResult`. diff --git a/clients/python/examples/kv.py b/clients/python/examples/kv.py new file mode 100644 index 0000000..ac47ea0 --- /dev/null +++ b/clients/python/examples/kv.py @@ -0,0 +1,15 @@ +"""Minimal CacheOnly put/get. Start supercache-node with -demo-keyspace first.""" + +import supercache + +def main() -> None: + client = supercache.dial("127.0.0.1:9000") + try: + client.put("cacheonly", "greeting", b"hello") + print(client.get("cacheonly", "greeting").decode()) + finally: + client.close() + + +if __name__ == "__main__": + main() diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml new file mode 100644 index 0000000..dc1d85c --- /dev/null +++ b/clients/python/pyproject.toml @@ -0,0 +1,19 @@ +[project] +name = "supercache" +version = "0.1.0" +description = "SuperCache Cache gRPC client for Python" +requires-python = ">=3.11" +dependencies = ["grpcio>=1.69,<2"] + +[project.optional-dependencies] +dev = ["pytest>=8", "grpcio-tools==1.69.0"] + +[tool.setuptools.packages.find] +where = ["src"] + +[build-system] +requires = ["setuptools>=68"] +build-backend = "setuptools.build_meta" + +[tool.pytest.ini_options] +testpaths = ["tests"] diff --git a/clients/python/src/supercache/__init__.py b/clients/python/src/supercache/__init__.py new file mode 100644 index 0000000..388b855 --- /dev/null +++ b/clients/python/src/supercache/__init__.py @@ -0,0 +1,49 @@ +"""SuperCache Cache client. Dial the cache port, not the peer port.""" + +from supercache.client import Client, dial, dial_tls +from supercache.types import ( + BitPos, + BitValue, + GeoMember, + HashField, + Present, + StreamEntry, + TLS, + TopKEntry, + TopKResult, + VSimHit, + ZMember, +) +from supercache.errors import ( + KeyErrorItem, + KeyErrors, + NotFound, + PeerFailure, + PeerFailures, + StatusError, +) +from supercache.session import Session + +__all__ = [ + "BitPos", + "BitValue", + "Client", + "GeoMember", + "HashField", + "KeyErrorItem", + "KeyErrors", + "NotFound", + "PeerFailure", + "PeerFailures", + "Present", + "Session", + "StatusError", + "StreamEntry", + "TLS", + "TopKEntry", + "TopKResult", + "VSimHit", + "ZMember", + "dial", + "dial_tls", +] diff --git a/clients/python/src/supercache/_gen/__init__.py b/clients/python/src/supercache/_gen/__init__.py new file mode 100644 index 0000000..6fa78ce --- /dev/null +++ b/clients/python/src/supercache/_gen/__init__.py @@ -0,0 +1 @@ +"""Generated Cache stubs. Do not edit.""" diff --git a/clients/python/src/supercache/_gen/cache_pb2.py b/clients/python/src/supercache/_gen/cache_pb2.py new file mode 100644 index 0000000..48af10c --- /dev/null +++ b/clients/python/src/supercache/_gen/cache_pb2.py @@ -0,0 +1,307 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: cache.proto +# Protobuf Python Version: 5.29.0 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 29, + 0, + '', + 'cache.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0b\x63\x61\x63he.proto\x12\x13supercache.cache.v1\"+\n\nGetRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\"+\n\x0bGetResponse\x12\r\n\x05\x66ound\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x0c\"^\n\nPutRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\x0c\x12\x11\n\tttl_nanos\x18\x04 \x01(\x03\x12\x0f\n\x07ttl_set\x18\x05 \x01(\x08\"\r\n\x0bPutResponse\" \n\x02KV\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\"n\n\x0ePutManyRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12&\n\x05items\x18\x02 \x03(\x0b\x32\x17.supercache.cache.v1.KV\x12\x11\n\tttl_nanos\x18\x03 \x01(\x03\x12\x0f\n\x07ttl_set\x18\x04 \x01(\x08\"a\n\x08KeyError\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x37\n\rpeer_failures\x18\x03 \x03(\x0b\x32 .supercache.cache.v1.PeerFailure\"@\n\x0fPutManyResponse\x12-\n\x06\x65rrors\x18\x01 \x03(\x0b\x32\x1d.supercache.cache.v1.KeyError\".\n\rDeleteRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0b\n\x03key\x18\x02 \x01(\t\"/\n\x0bPeerFailure\x12\x0f\n\x07peer_id\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t\"I\n\x0e\x44\x65leteResponse\x12\x37\n\rpeer_failures\x18\x01 \x03(\x0b\x32 .supercache.cache.v1.PeerFailure\"3\n\x11\x44\x65leteManyRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04keys\x18\x02 \x03(\t\"C\n\x12\x44\x65leteManyResponse\x12-\n\x06\x65rrors\x18\x01 \x03(\x0b\x32\x1d.supercache.cache.v1.KeyError\"?\n\x0f\x42loomAddRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04item\x18\x03 \x01(\x0c\"\x12\n\x10\x42loomAddResponse\"@\n\x10\x42loomTestRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04item\x18\x03 \x01(\x0c\"\"\n\x11\x42loomTestResponse\x12\r\n\x05maybe\x18\x01 \x01(\x08\"=\n\rSetAddRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04item\x18\x03 \x01(\x0c\"\x10\n\x0eSetAddResponse\"@\n\x10SetRemoveRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04item\x18\x03 \x01(\x0c\"\x13\n\x11SetRemoveResponse\"B\n\x12SetContainsRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04item\x18\x03 \x01(\x0c\"&\n\x13SetContainsResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\"0\n\x0eSetCardRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x1f\n\x0fSetCardResponse\x12\x0c\n\x04\x63\x61rd\x18\x01 \x01(\x03\"3\n\x11SetMembersRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"%\n\x12SetMembersResponse\x12\x0f\n\x07members\x18\x01 \x03(\x0c\"(\n\x07ZMember\x12\x0e\n\x06member\x18\x01 \x01(\x0c\x12\r\n\x05score\x18\x02 \x01(\x01\"L\n\x0bZAddRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06member\x18\x03 \x01(\x0c\x12\r\n\x05score\x18\x04 \x01(\x01\"\x0e\n\x0cZAddResponse\"=\n\x0bZRemRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06member\x18\x03 \x01(\x0c\"\x0e\n\x0cZRemResponse\"?\n\rZScoreRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06member\x18\x03 \x01(\x0c\"0\n\x0eZScoreResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12\r\n\x05score\x18\x02 \x01(\x01\".\n\x0cZCardRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x1d\n\rZCardResponse\x12\x0c\n\x04\x63\x61rd\x18\x01 \x01(\x03\"L\n\rZRangeRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05start\x18\x03 \x01(\x05\x12\x0c\n\x04stop\x18\x04 \x01(\x05\"P\n\x14ZRangeByScoreRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0b\n\x03min\x18\x03 \x01(\x01\x12\x0b\n\x03max\x18\x04 \x01(\x01\"?\n\x0eZRangeResponse\x12-\n\x07members\x18\x01 \x03(\x0b\x32\x1c.supercache.cache.v1.ZMember\"J\n\tGeoMember\x12\x0e\n\x06member\x18\x01 \x01(\x0c\x12\x0b\n\x03lon\x18\x02 \x01(\x01\x12\x0b\n\x03lat\x18\x03 \x01(\x01\x12\x13\n\x0b\x64ist_meters\x18\x04 \x01(\x01\"Y\n\rGeoAddRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06member\x18\x03 \x01(\x0c\x12\x0b\n\x03lon\x18\x04 \x01(\x01\x12\x0b\n\x03lat\x18\x05 \x01(\x01\"\x10\n\x0eGeoAddResponse\"?\n\rGeoRemRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06member\x18\x03 \x01(\x0c\"\x10\n\x0eGeoRemResponse\"?\n\rGeoPosRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06member\x18\x03 \x01(\x0c\";\n\x0eGeoPosResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12\x0b\n\x03lon\x18\x02 \x01(\x01\x12\x0b\n\x03lat\x18\x03 \x01(\x01\"0\n\x0eGeoCardRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x1f\n\x0fGeoCardResponse\x12\x0c\n\x04\x63\x61rd\x18\x01 \x01(\x03\"F\n\x0eGeoDistRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\t\n\x01\x61\x18\x03 \x01(\x0c\x12\t\n\x01\x62\x18\x04 \x01(\x0c\"2\n\x0fGeoDistResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12\x0e\n\x06meters\x18\x02 \x01(\x01\"r\n\x10GeoRadiusRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0b\n\x03lon\x18\x03 \x01(\x01\x12\x0b\n\x03lat\x18\x04 \x01(\x01\x12\x15\n\rradius_meters\x18\x05 \x01(\x01\x12\r\n\x05limit\x18\x06 \x01(\x05\"D\n\x11GeoRadiusResponse\x12/\n\x07members\x18\x01 \x03(\x0b\x32\x1e.supercache.cache.v1.GeoMember\"<\n\x0cLPushRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04item\x18\x03 \x01(\x0c\"\x0f\n\rLPushResponse\"<\n\x0cRPushRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04item\x18\x03 \x01(\x0c\"\x0f\n\rRPushResponse\"-\n\x0bLPopRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"-\n\x0cLPopResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12\x0c\n\x04item\x18\x02 \x01(\x0c\"-\n\x0bRPopRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"-\n\x0cRPopResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12\x0c\n\x04item\x18\x02 \x01(\x0c\"-\n\x0bLLenRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x1b\n\x0cLLenResponse\x12\x0b\n\x03len\x18\x01 \x01(\x03\">\n\rLIndexRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05index\x18\x03 \x01(\x05\"/\n\x0eLIndexResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12\x0c\n\x04item\x18\x02 \x01(\x0c\"L\n\rLRangeRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05start\x18\x03 \x01(\x05\x12\x0c\n\x04stop\x18\x04 \x01(\x05\"\x1f\n\x0eLRangeResponse\x12\r\n\x05items\x18\x01 \x03(\x0c\"K\n\x0bHSetRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05\x66ield\x18\x03 \x01(\x0c\x12\r\n\x05value\x18\x04 \x01(\x0c\"\x0e\n\x0cHSetResponse\"<\n\x0bHGetRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05\x66ield\x18\x03 \x01(\x0c\".\n\x0cHGetResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x0c\"<\n\x0bHDelRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05\x66ield\x18\x03 \x01(\x0c\"\x0e\n\x0cHDelResponse\"?\n\x0eHExistsRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05\x66ield\x18\x03 \x01(\x0c\"\"\n\x0fHExistsResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\"-\n\x0bHLenRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x1b\n\x0cHLenResponse\x12\x0b\n\x03len\x18\x01 \x01(\x03\"0\n\x0eHGetAllRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\")\n\tHashField\x12\r\n\x05\x66ield\x18\x01 \x01(\x0c\x12\r\n\x05value\x18\x02 \x01(\x0c\"A\n\x0fHGetAllResponse\x12.\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x1e.supercache.cache.v1.HashField\"<\n\x0bIncrRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05\x64\x65lta\x18\x03 \x01(\x03\"\x1d\n\x0cIncrResponse\x12\r\n\x05value\x18\x01 \x01(\x03\"3\n\x11\x43ounterGetRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"4\n\x12\x43ounterGetResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x03\"M\n\x0eJsonSetRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04path\x18\x03 \x01(\t\x12\r\n\x05value\x18\x04 \x01(\x0c\"\x11\n\x0fJsonSetResponse\">\n\x0eJsonGetRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04path\x18\x03 \x01(\t\"1\n\x0fJsonGetResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x0c\">\n\x0eJsonDelRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04path\x18\x03 \x01(\t\"\x11\n\x0fJsonDelResponse\"L\n\rBitSetRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06offset\x18\x03 \x01(\x04\x12\x0b\n\x03\x62it\x18\x04 \x01(\x08\"\x10\n\x0e\x42itSetResponse\"?\n\rBitGetRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06offset\x18\x03 \x01(\x04\".\n\x0e\x42itGetResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12\x0b\n\x03\x62it\x18\x02 \x01(\x08\"M\n\x0f\x42itCountRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05start\x18\x03 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x04 \x01(\x05\"!\n\x10\x42itCountResponse\x12\r\n\x05\x63ount\x18\x01 \x01(\x03\"X\n\rBitPosRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0b\n\x03\x62it\x18\x03 \x01(\x08\x12\r\n\x05start\x18\x04 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x05 \x01(\x05\",\n\x0e\x42itPosResponse\x12\r\n\x05\x66ound\x18\x01 \x01(\x08\x12\x0b\n\x03pos\x18\x02 \x01(\x03\"=\n\rHLLAddRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04item\x18\x03 \x01(\x0c\"\x10\n\x0eHLLAddResponse\"1\n\x0fHLLCountRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"2\n\x10HLLCountResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12\r\n\x05\x63ount\x18\x02 \x01(\x04\">\n\x0eTopKAddRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04item\x18\x03 \x01(\x0c\"\x11\n\x0fTopKAddResponse\"1\n\x0fTopKListRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"(\n\tTopKEntry\x12\x0c\n\x04item\x18\x01 \x01(\x0c\x12\r\n\x05\x63ount\x18\x02 \x01(\x04\"T\n\x10TopKListResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12/\n\x07\x65ntries\x18\x02 \x03(\x0b\x32\x1e.supercache.cache.v1.TopKEntry\"I\n\x0e\x43MSIncrRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04item\x18\x03 \x01(\x0c\x12\t\n\x01n\x18\x04 \x01(\x04\"\x11\n\x0f\x43MSIncrResponse\"?\n\x0f\x43MSQueryRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04item\x18\x03 \x01(\x0c\"2\n\x10\x43MSQueryResponse\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12\r\n\x05\x63ount\x18\x02 \x01(\x04\"J\n\x0bVAddRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06member\x18\x03 \x01(\x0c\x12\x0b\n\x03vec\x18\x04 \x03(\x02\"\x0e\n\x0cVAddResponse\"=\n\x0bVRemRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06member\x18\x03 \x01(\x0c\"\x0e\n\x0cVRemResponse\"E\n\x0bVSimRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0b\n\x03vec\x18\x03 \x03(\x02\x12\t\n\x01k\x18\x04 \x01(\x05\"(\n\x07VSimHit\x12\x0e\n\x06member\x18\x01 \x01(\x0c\x12\r\n\x05score\x18\x02 \x01(\x02\":\n\x0cVSimResponse\x12*\n\x04hits\x18\x01 \x03(\x0b\x32\x1c.supercache.cache.v1.VSimHit\".\n\x0cVCardRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"+\n\rVCardResponse\x12\t\n\x01n\x18\x01 \x01(\x03\x12\x0f\n\x07present\x18\x02 \x01(\x08\"-\n\x0bVDimRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\",\n\x0cVDimResponse\x12\x0b\n\x03\x64im\x18\x01 \x01(\x05\x12\x0f\n\x07present\x18\x02 \x01(\x08\"=\n\x0bVEmbRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06member\x18\x03 \x01(\x0c\"*\n\x0cVEmbResponse\x12\x0b\n\x03vec\x18\x01 \x03(\x02\x12\r\n\x05\x66ound\x18\x02 \x01(\x08\"*\n\x0bStreamEntry\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\">\n\x0bXAddRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07payload\x18\x03 \x01(\x0c\"\x1a\n\x0cXAddResponse\x12\n\n\x02id\x18\x01 \x01(\t\"Z\n\rXRangeRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05start\x18\x03 \x01(\t\x12\x0b\n\x03\x65nd\x18\x04 \x01(\t\x12\r\n\x05\x63ount\x18\x05 \x01(\x05\"]\n\x10XRevRangeRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05start\x18\x03 \x01(\t\x12\x0b\n\x03\x65nd\x18\x04 \x01(\t\x12\r\n\x05\x63ount\x18\x05 \x01(\x05\"C\n\x0eXRangeResponse\x12\x31\n\x07\x65ntries\x18\x01 \x03(\x0b\x32 .supercache.cache.v1.StreamEntry\"-\n\x0bXLenRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"*\n\x0cXLenResponse\x12\t\n\x01n\x18\x01 \x01(\x03\x12\x0f\n\x07present\x18\x02 \x01(\x08\"9\n\x0bXDelRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\n\n\x02id\x18\x03 \x01(\t\"\x0e\n\x0cXDelResponse\"?\n\x0cXTrimRequest\x12\x10\n\x08keyspace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07max_len\x18\x03 \x01(\x05\"\x0f\n\rXTrimResponse2\xdb)\n\x05\x43\x61\x63he\x12H\n\x03Get\x12\x1f.supercache.cache.v1.GetRequest\x1a .supercache.cache.v1.GetResponse\x12H\n\x03Put\x12\x1f.supercache.cache.v1.PutRequest\x1a .supercache.cache.v1.PutResponse\x12T\n\x07PutMany\x12#.supercache.cache.v1.PutManyRequest\x1a$.supercache.cache.v1.PutManyResponse\x12Q\n\x06\x44\x65lete\x12\".supercache.cache.v1.DeleteRequest\x1a#.supercache.cache.v1.DeleteResponse\x12]\n\nDeleteMany\x12&.supercache.cache.v1.DeleteManyRequest\x1a\'.supercache.cache.v1.DeleteManyResponse\x12W\n\x08\x42loomAdd\x12$.supercache.cache.v1.BloomAddRequest\x1a%.supercache.cache.v1.BloomAddResponse\x12Z\n\tBloomTest\x12%.supercache.cache.v1.BloomTestRequest\x1a&.supercache.cache.v1.BloomTestResponse\x12Q\n\x06SetAdd\x12\".supercache.cache.v1.SetAddRequest\x1a#.supercache.cache.v1.SetAddResponse\x12Z\n\tSetRemove\x12%.supercache.cache.v1.SetRemoveRequest\x1a&.supercache.cache.v1.SetRemoveResponse\x12`\n\x0bSetContains\x12\'.supercache.cache.v1.SetContainsRequest\x1a(.supercache.cache.v1.SetContainsResponse\x12T\n\x07SetCard\x12#.supercache.cache.v1.SetCardRequest\x1a$.supercache.cache.v1.SetCardResponse\x12]\n\nSetMembers\x12&.supercache.cache.v1.SetMembersRequest\x1a\'.supercache.cache.v1.SetMembersResponse\x12K\n\x04ZAdd\x12 .supercache.cache.v1.ZAddRequest\x1a!.supercache.cache.v1.ZAddResponse\x12K\n\x04ZRem\x12 .supercache.cache.v1.ZRemRequest\x1a!.supercache.cache.v1.ZRemResponse\x12Q\n\x06ZScore\x12\".supercache.cache.v1.ZScoreRequest\x1a#.supercache.cache.v1.ZScoreResponse\x12N\n\x05ZCard\x12!.supercache.cache.v1.ZCardRequest\x1a\".supercache.cache.v1.ZCardResponse\x12Q\n\x06ZRange\x12\".supercache.cache.v1.ZRangeRequest\x1a#.supercache.cache.v1.ZRangeResponse\x12_\n\rZRangeByScore\x12).supercache.cache.v1.ZRangeByScoreRequest\x1a#.supercache.cache.v1.ZRangeResponse\x12Q\n\x06GeoAdd\x12\".supercache.cache.v1.GeoAddRequest\x1a#.supercache.cache.v1.GeoAddResponse\x12Q\n\x06GeoRem\x12\".supercache.cache.v1.GeoRemRequest\x1a#.supercache.cache.v1.GeoRemResponse\x12Q\n\x06GeoPos\x12\".supercache.cache.v1.GeoPosRequest\x1a#.supercache.cache.v1.GeoPosResponse\x12T\n\x07GeoCard\x12#.supercache.cache.v1.GeoCardRequest\x1a$.supercache.cache.v1.GeoCardResponse\x12T\n\x07GeoDist\x12#.supercache.cache.v1.GeoDistRequest\x1a$.supercache.cache.v1.GeoDistResponse\x12Z\n\tGeoRadius\x12%.supercache.cache.v1.GeoRadiusRequest\x1a&.supercache.cache.v1.GeoRadiusResponse\x12N\n\x05LPush\x12!.supercache.cache.v1.LPushRequest\x1a\".supercache.cache.v1.LPushResponse\x12N\n\x05RPush\x12!.supercache.cache.v1.RPushRequest\x1a\".supercache.cache.v1.RPushResponse\x12K\n\x04LPop\x12 .supercache.cache.v1.LPopRequest\x1a!.supercache.cache.v1.LPopResponse\x12K\n\x04RPop\x12 .supercache.cache.v1.RPopRequest\x1a!.supercache.cache.v1.RPopResponse\x12K\n\x04LLen\x12 .supercache.cache.v1.LLenRequest\x1a!.supercache.cache.v1.LLenResponse\x12Q\n\x06LIndex\x12\".supercache.cache.v1.LIndexRequest\x1a#.supercache.cache.v1.LIndexResponse\x12Q\n\x06LRange\x12\".supercache.cache.v1.LRangeRequest\x1a#.supercache.cache.v1.LRangeResponse\x12K\n\x04HSet\x12 .supercache.cache.v1.HSetRequest\x1a!.supercache.cache.v1.HSetResponse\x12K\n\x04HGet\x12 .supercache.cache.v1.HGetRequest\x1a!.supercache.cache.v1.HGetResponse\x12K\n\x04HDel\x12 .supercache.cache.v1.HDelRequest\x1a!.supercache.cache.v1.HDelResponse\x12T\n\x07HExists\x12#.supercache.cache.v1.HExistsRequest\x1a$.supercache.cache.v1.HExistsResponse\x12K\n\x04HLen\x12 .supercache.cache.v1.HLenRequest\x1a!.supercache.cache.v1.HLenResponse\x12T\n\x07HGetAll\x12#.supercache.cache.v1.HGetAllRequest\x1a$.supercache.cache.v1.HGetAllResponse\x12K\n\x04Incr\x12 .supercache.cache.v1.IncrRequest\x1a!.supercache.cache.v1.IncrResponse\x12]\n\nCounterGet\x12&.supercache.cache.v1.CounterGetRequest\x1a\'.supercache.cache.v1.CounterGetResponse\x12T\n\x07JsonSet\x12#.supercache.cache.v1.JsonSetRequest\x1a$.supercache.cache.v1.JsonSetResponse\x12T\n\x07JsonGet\x12#.supercache.cache.v1.JsonGetRequest\x1a$.supercache.cache.v1.JsonGetResponse\x12T\n\x07JsonDel\x12#.supercache.cache.v1.JsonDelRequest\x1a$.supercache.cache.v1.JsonDelResponse\x12Q\n\x06\x42itSet\x12\".supercache.cache.v1.BitSetRequest\x1a#.supercache.cache.v1.BitSetResponse\x12Q\n\x06\x42itGet\x12\".supercache.cache.v1.BitGetRequest\x1a#.supercache.cache.v1.BitGetResponse\x12W\n\x08\x42itCount\x12$.supercache.cache.v1.BitCountRequest\x1a%.supercache.cache.v1.BitCountResponse\x12Q\n\x06\x42itPos\x12\".supercache.cache.v1.BitPosRequest\x1a#.supercache.cache.v1.BitPosResponse\x12Q\n\x06HLLAdd\x12\".supercache.cache.v1.HLLAddRequest\x1a#.supercache.cache.v1.HLLAddResponse\x12W\n\x08HLLCount\x12$.supercache.cache.v1.HLLCountRequest\x1a%.supercache.cache.v1.HLLCountResponse\x12T\n\x07TopKAdd\x12#.supercache.cache.v1.TopKAddRequest\x1a$.supercache.cache.v1.TopKAddResponse\x12W\n\x08TopKList\x12$.supercache.cache.v1.TopKListRequest\x1a%.supercache.cache.v1.TopKListResponse\x12T\n\x07\x43MSIncr\x12#.supercache.cache.v1.CMSIncrRequest\x1a$.supercache.cache.v1.CMSIncrResponse\x12W\n\x08\x43MSQuery\x12$.supercache.cache.v1.CMSQueryRequest\x1a%.supercache.cache.v1.CMSQueryResponse\x12K\n\x04VAdd\x12 .supercache.cache.v1.VAddRequest\x1a!.supercache.cache.v1.VAddResponse\x12K\n\x04VRem\x12 .supercache.cache.v1.VRemRequest\x1a!.supercache.cache.v1.VRemResponse\x12K\n\x04VSim\x12 .supercache.cache.v1.VSimRequest\x1a!.supercache.cache.v1.VSimResponse\x12N\n\x05VCard\x12!.supercache.cache.v1.VCardRequest\x1a\".supercache.cache.v1.VCardResponse\x12K\n\x04VDim\x12 .supercache.cache.v1.VDimRequest\x1a!.supercache.cache.v1.VDimResponse\x12K\n\x04VEmb\x12 .supercache.cache.v1.VEmbRequest\x1a!.supercache.cache.v1.VEmbResponse\x12K\n\x04XAdd\x12 .supercache.cache.v1.XAddRequest\x1a!.supercache.cache.v1.XAddResponse\x12Q\n\x06XRange\x12\".supercache.cache.v1.XRangeRequest\x1a#.supercache.cache.v1.XRangeResponse\x12W\n\tXRevRange\x12%.supercache.cache.v1.XRevRangeRequest\x1a#.supercache.cache.v1.XRangeResponse\x12K\n\x04XLen\x12 .supercache.cache.v1.XLenRequest\x1a!.supercache.cache.v1.XLenResponse\x12K\n\x04XDel\x12 .supercache.cache.v1.XDelRequest\x1a!.supercache.cache.v1.XDelResponse\x12N\n\x05XTrim\x12!.supercache.cache.v1.XTrimRequest\x1a\".supercache.cache.v1.XTrimResponseB9Z7github.com/Code0987/supercache/api/gen/cache/v1;cachev1b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'cache_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'Z7github.com/Code0987/supercache/api/gen/cache/v1;cachev1' + _globals['_GETREQUEST']._serialized_start=36 + _globals['_GETREQUEST']._serialized_end=79 + _globals['_GETRESPONSE']._serialized_start=81 + _globals['_GETRESPONSE']._serialized_end=124 + _globals['_PUTREQUEST']._serialized_start=126 + _globals['_PUTREQUEST']._serialized_end=220 + _globals['_PUTRESPONSE']._serialized_start=222 + _globals['_PUTRESPONSE']._serialized_end=235 + _globals['_KV']._serialized_start=237 + _globals['_KV']._serialized_end=269 + _globals['_PUTMANYREQUEST']._serialized_start=271 + _globals['_PUTMANYREQUEST']._serialized_end=381 + _globals['_KEYERROR']._serialized_start=383 + _globals['_KEYERROR']._serialized_end=480 + _globals['_PUTMANYRESPONSE']._serialized_start=482 + _globals['_PUTMANYRESPONSE']._serialized_end=546 + _globals['_DELETEREQUEST']._serialized_start=548 + _globals['_DELETEREQUEST']._serialized_end=594 + _globals['_PEERFAILURE']._serialized_start=596 + _globals['_PEERFAILURE']._serialized_end=643 + _globals['_DELETERESPONSE']._serialized_start=645 + _globals['_DELETERESPONSE']._serialized_end=718 + _globals['_DELETEMANYREQUEST']._serialized_start=720 + _globals['_DELETEMANYREQUEST']._serialized_end=771 + _globals['_DELETEMANYRESPONSE']._serialized_start=773 + _globals['_DELETEMANYRESPONSE']._serialized_end=840 + _globals['_BLOOMADDREQUEST']._serialized_start=842 + _globals['_BLOOMADDREQUEST']._serialized_end=905 + _globals['_BLOOMADDRESPONSE']._serialized_start=907 + _globals['_BLOOMADDRESPONSE']._serialized_end=925 + _globals['_BLOOMTESTREQUEST']._serialized_start=927 + _globals['_BLOOMTESTREQUEST']._serialized_end=991 + _globals['_BLOOMTESTRESPONSE']._serialized_start=993 + _globals['_BLOOMTESTRESPONSE']._serialized_end=1027 + _globals['_SETADDREQUEST']._serialized_start=1029 + _globals['_SETADDREQUEST']._serialized_end=1090 + _globals['_SETADDRESPONSE']._serialized_start=1092 + _globals['_SETADDRESPONSE']._serialized_end=1108 + _globals['_SETREMOVEREQUEST']._serialized_start=1110 + _globals['_SETREMOVEREQUEST']._serialized_end=1174 + _globals['_SETREMOVERESPONSE']._serialized_start=1176 + _globals['_SETREMOVERESPONSE']._serialized_end=1195 + _globals['_SETCONTAINSREQUEST']._serialized_start=1197 + _globals['_SETCONTAINSREQUEST']._serialized_end=1263 + _globals['_SETCONTAINSRESPONSE']._serialized_start=1265 + _globals['_SETCONTAINSRESPONSE']._serialized_end=1303 + _globals['_SETCARDREQUEST']._serialized_start=1305 + _globals['_SETCARDREQUEST']._serialized_end=1353 + _globals['_SETCARDRESPONSE']._serialized_start=1355 + _globals['_SETCARDRESPONSE']._serialized_end=1386 + _globals['_SETMEMBERSREQUEST']._serialized_start=1388 + _globals['_SETMEMBERSREQUEST']._serialized_end=1439 + _globals['_SETMEMBERSRESPONSE']._serialized_start=1441 + _globals['_SETMEMBERSRESPONSE']._serialized_end=1478 + _globals['_ZMEMBER']._serialized_start=1480 + _globals['_ZMEMBER']._serialized_end=1520 + _globals['_ZADDREQUEST']._serialized_start=1522 + _globals['_ZADDREQUEST']._serialized_end=1598 + _globals['_ZADDRESPONSE']._serialized_start=1600 + _globals['_ZADDRESPONSE']._serialized_end=1614 + _globals['_ZREMREQUEST']._serialized_start=1616 + _globals['_ZREMREQUEST']._serialized_end=1677 + _globals['_ZREMRESPONSE']._serialized_start=1679 + _globals['_ZREMRESPONSE']._serialized_end=1693 + _globals['_ZSCOREREQUEST']._serialized_start=1695 + _globals['_ZSCOREREQUEST']._serialized_end=1758 + _globals['_ZSCORERESPONSE']._serialized_start=1760 + _globals['_ZSCORERESPONSE']._serialized_end=1808 + _globals['_ZCARDREQUEST']._serialized_start=1810 + _globals['_ZCARDREQUEST']._serialized_end=1856 + _globals['_ZCARDRESPONSE']._serialized_start=1858 + _globals['_ZCARDRESPONSE']._serialized_end=1887 + _globals['_ZRANGEREQUEST']._serialized_start=1889 + _globals['_ZRANGEREQUEST']._serialized_end=1965 + _globals['_ZRANGEBYSCOREREQUEST']._serialized_start=1967 + _globals['_ZRANGEBYSCOREREQUEST']._serialized_end=2047 + _globals['_ZRANGERESPONSE']._serialized_start=2049 + _globals['_ZRANGERESPONSE']._serialized_end=2112 + _globals['_GEOMEMBER']._serialized_start=2114 + _globals['_GEOMEMBER']._serialized_end=2188 + _globals['_GEOADDREQUEST']._serialized_start=2190 + _globals['_GEOADDREQUEST']._serialized_end=2279 + _globals['_GEOADDRESPONSE']._serialized_start=2281 + _globals['_GEOADDRESPONSE']._serialized_end=2297 + _globals['_GEOREMREQUEST']._serialized_start=2299 + _globals['_GEOREMREQUEST']._serialized_end=2362 + _globals['_GEOREMRESPONSE']._serialized_start=2364 + _globals['_GEOREMRESPONSE']._serialized_end=2380 + _globals['_GEOPOSREQUEST']._serialized_start=2382 + _globals['_GEOPOSREQUEST']._serialized_end=2445 + _globals['_GEOPOSRESPONSE']._serialized_start=2447 + _globals['_GEOPOSRESPONSE']._serialized_end=2506 + _globals['_GEOCARDREQUEST']._serialized_start=2508 + _globals['_GEOCARDREQUEST']._serialized_end=2556 + _globals['_GEOCARDRESPONSE']._serialized_start=2558 + _globals['_GEOCARDRESPONSE']._serialized_end=2589 + _globals['_GEODISTREQUEST']._serialized_start=2591 + _globals['_GEODISTREQUEST']._serialized_end=2661 + _globals['_GEODISTRESPONSE']._serialized_start=2663 + _globals['_GEODISTRESPONSE']._serialized_end=2713 + _globals['_GEORADIUSREQUEST']._serialized_start=2715 + _globals['_GEORADIUSREQUEST']._serialized_end=2829 + _globals['_GEORADIUSRESPONSE']._serialized_start=2831 + _globals['_GEORADIUSRESPONSE']._serialized_end=2899 + _globals['_LPUSHREQUEST']._serialized_start=2901 + _globals['_LPUSHREQUEST']._serialized_end=2961 + _globals['_LPUSHRESPONSE']._serialized_start=2963 + _globals['_LPUSHRESPONSE']._serialized_end=2978 + _globals['_RPUSHREQUEST']._serialized_start=2980 + _globals['_RPUSHREQUEST']._serialized_end=3040 + _globals['_RPUSHRESPONSE']._serialized_start=3042 + _globals['_RPUSHRESPONSE']._serialized_end=3057 + _globals['_LPOPREQUEST']._serialized_start=3059 + _globals['_LPOPREQUEST']._serialized_end=3104 + _globals['_LPOPRESPONSE']._serialized_start=3106 + _globals['_LPOPRESPONSE']._serialized_end=3151 + _globals['_RPOPREQUEST']._serialized_start=3153 + _globals['_RPOPREQUEST']._serialized_end=3198 + _globals['_RPOPRESPONSE']._serialized_start=3200 + _globals['_RPOPRESPONSE']._serialized_end=3245 + _globals['_LLENREQUEST']._serialized_start=3247 + _globals['_LLENREQUEST']._serialized_end=3292 + _globals['_LLENRESPONSE']._serialized_start=3294 + _globals['_LLENRESPONSE']._serialized_end=3321 + _globals['_LINDEXREQUEST']._serialized_start=3323 + _globals['_LINDEXREQUEST']._serialized_end=3385 + _globals['_LINDEXRESPONSE']._serialized_start=3387 + _globals['_LINDEXRESPONSE']._serialized_end=3434 + _globals['_LRANGEREQUEST']._serialized_start=3436 + _globals['_LRANGEREQUEST']._serialized_end=3512 + _globals['_LRANGERESPONSE']._serialized_start=3514 + _globals['_LRANGERESPONSE']._serialized_end=3545 + _globals['_HSETREQUEST']._serialized_start=3547 + _globals['_HSETREQUEST']._serialized_end=3622 + _globals['_HSETRESPONSE']._serialized_start=3624 + _globals['_HSETRESPONSE']._serialized_end=3638 + _globals['_HGETREQUEST']._serialized_start=3640 + _globals['_HGETREQUEST']._serialized_end=3700 + _globals['_HGETRESPONSE']._serialized_start=3702 + _globals['_HGETRESPONSE']._serialized_end=3748 + _globals['_HDELREQUEST']._serialized_start=3750 + _globals['_HDELREQUEST']._serialized_end=3810 + _globals['_HDELRESPONSE']._serialized_start=3812 + _globals['_HDELRESPONSE']._serialized_end=3826 + _globals['_HEXISTSREQUEST']._serialized_start=3828 + _globals['_HEXISTSREQUEST']._serialized_end=3891 + _globals['_HEXISTSRESPONSE']._serialized_start=3893 + _globals['_HEXISTSRESPONSE']._serialized_end=3927 + _globals['_HLENREQUEST']._serialized_start=3929 + _globals['_HLENREQUEST']._serialized_end=3974 + _globals['_HLENRESPONSE']._serialized_start=3976 + _globals['_HLENRESPONSE']._serialized_end=4003 + _globals['_HGETALLREQUEST']._serialized_start=4005 + _globals['_HGETALLREQUEST']._serialized_end=4053 + _globals['_HASHFIELD']._serialized_start=4055 + _globals['_HASHFIELD']._serialized_end=4096 + _globals['_HGETALLRESPONSE']._serialized_start=4098 + _globals['_HGETALLRESPONSE']._serialized_end=4163 + _globals['_INCRREQUEST']._serialized_start=4165 + _globals['_INCRREQUEST']._serialized_end=4225 + _globals['_INCRRESPONSE']._serialized_start=4227 + _globals['_INCRRESPONSE']._serialized_end=4256 + _globals['_COUNTERGETREQUEST']._serialized_start=4258 + _globals['_COUNTERGETREQUEST']._serialized_end=4309 + _globals['_COUNTERGETRESPONSE']._serialized_start=4311 + _globals['_COUNTERGETRESPONSE']._serialized_end=4363 + _globals['_JSONSETREQUEST']._serialized_start=4365 + _globals['_JSONSETREQUEST']._serialized_end=4442 + _globals['_JSONSETRESPONSE']._serialized_start=4444 + _globals['_JSONSETRESPONSE']._serialized_end=4461 + _globals['_JSONGETREQUEST']._serialized_start=4463 + _globals['_JSONGETREQUEST']._serialized_end=4525 + _globals['_JSONGETRESPONSE']._serialized_start=4527 + _globals['_JSONGETRESPONSE']._serialized_end=4576 + _globals['_JSONDELREQUEST']._serialized_start=4578 + _globals['_JSONDELREQUEST']._serialized_end=4640 + _globals['_JSONDELRESPONSE']._serialized_start=4642 + _globals['_JSONDELRESPONSE']._serialized_end=4659 + _globals['_BITSETREQUEST']._serialized_start=4661 + _globals['_BITSETREQUEST']._serialized_end=4737 + _globals['_BITSETRESPONSE']._serialized_start=4739 + _globals['_BITSETRESPONSE']._serialized_end=4755 + _globals['_BITGETREQUEST']._serialized_start=4757 + _globals['_BITGETREQUEST']._serialized_end=4820 + _globals['_BITGETRESPONSE']._serialized_start=4822 + _globals['_BITGETRESPONSE']._serialized_end=4868 + _globals['_BITCOUNTREQUEST']._serialized_start=4870 + _globals['_BITCOUNTREQUEST']._serialized_end=4947 + _globals['_BITCOUNTRESPONSE']._serialized_start=4949 + _globals['_BITCOUNTRESPONSE']._serialized_end=4982 + _globals['_BITPOSREQUEST']._serialized_start=4984 + _globals['_BITPOSREQUEST']._serialized_end=5072 + _globals['_BITPOSRESPONSE']._serialized_start=5074 + _globals['_BITPOSRESPONSE']._serialized_end=5118 + _globals['_HLLADDREQUEST']._serialized_start=5120 + _globals['_HLLADDREQUEST']._serialized_end=5181 + _globals['_HLLADDRESPONSE']._serialized_start=5183 + _globals['_HLLADDRESPONSE']._serialized_end=5199 + _globals['_HLLCOUNTREQUEST']._serialized_start=5201 + _globals['_HLLCOUNTREQUEST']._serialized_end=5250 + _globals['_HLLCOUNTRESPONSE']._serialized_start=5252 + _globals['_HLLCOUNTRESPONSE']._serialized_end=5302 + _globals['_TOPKADDREQUEST']._serialized_start=5304 + _globals['_TOPKADDREQUEST']._serialized_end=5366 + _globals['_TOPKADDRESPONSE']._serialized_start=5368 + _globals['_TOPKADDRESPONSE']._serialized_end=5385 + _globals['_TOPKLISTREQUEST']._serialized_start=5387 + _globals['_TOPKLISTREQUEST']._serialized_end=5436 + _globals['_TOPKENTRY']._serialized_start=5438 + _globals['_TOPKENTRY']._serialized_end=5478 + _globals['_TOPKLISTRESPONSE']._serialized_start=5480 + _globals['_TOPKLISTRESPONSE']._serialized_end=5564 + _globals['_CMSINCRREQUEST']._serialized_start=5566 + _globals['_CMSINCRREQUEST']._serialized_end=5639 + _globals['_CMSINCRRESPONSE']._serialized_start=5641 + _globals['_CMSINCRRESPONSE']._serialized_end=5658 + _globals['_CMSQUERYREQUEST']._serialized_start=5660 + _globals['_CMSQUERYREQUEST']._serialized_end=5723 + _globals['_CMSQUERYRESPONSE']._serialized_start=5725 + _globals['_CMSQUERYRESPONSE']._serialized_end=5775 + _globals['_VADDREQUEST']._serialized_start=5777 + _globals['_VADDREQUEST']._serialized_end=5851 + _globals['_VADDRESPONSE']._serialized_start=5853 + _globals['_VADDRESPONSE']._serialized_end=5867 + _globals['_VREMREQUEST']._serialized_start=5869 + _globals['_VREMREQUEST']._serialized_end=5930 + _globals['_VREMRESPONSE']._serialized_start=5932 + _globals['_VREMRESPONSE']._serialized_end=5946 + _globals['_VSIMREQUEST']._serialized_start=5948 + _globals['_VSIMREQUEST']._serialized_end=6017 + _globals['_VSIMHIT']._serialized_start=6019 + _globals['_VSIMHIT']._serialized_end=6059 + _globals['_VSIMRESPONSE']._serialized_start=6061 + _globals['_VSIMRESPONSE']._serialized_end=6119 + _globals['_VCARDREQUEST']._serialized_start=6121 + _globals['_VCARDREQUEST']._serialized_end=6167 + _globals['_VCARDRESPONSE']._serialized_start=6169 + _globals['_VCARDRESPONSE']._serialized_end=6212 + _globals['_VDIMREQUEST']._serialized_start=6214 + _globals['_VDIMREQUEST']._serialized_end=6259 + _globals['_VDIMRESPONSE']._serialized_start=6261 + _globals['_VDIMRESPONSE']._serialized_end=6305 + _globals['_VEMBREQUEST']._serialized_start=6307 + _globals['_VEMBREQUEST']._serialized_end=6368 + _globals['_VEMBRESPONSE']._serialized_start=6370 + _globals['_VEMBRESPONSE']._serialized_end=6412 + _globals['_STREAMENTRY']._serialized_start=6414 + _globals['_STREAMENTRY']._serialized_end=6456 + _globals['_XADDREQUEST']._serialized_start=6458 + _globals['_XADDREQUEST']._serialized_end=6520 + _globals['_XADDRESPONSE']._serialized_start=6522 + _globals['_XADDRESPONSE']._serialized_end=6548 + _globals['_XRANGEREQUEST']._serialized_start=6550 + _globals['_XRANGEREQUEST']._serialized_end=6640 + _globals['_XREVRANGEREQUEST']._serialized_start=6642 + _globals['_XREVRANGEREQUEST']._serialized_end=6735 + _globals['_XRANGERESPONSE']._serialized_start=6737 + _globals['_XRANGERESPONSE']._serialized_end=6804 + _globals['_XLENREQUEST']._serialized_start=6806 + _globals['_XLENREQUEST']._serialized_end=6851 + _globals['_XLENRESPONSE']._serialized_start=6853 + _globals['_XLENRESPONSE']._serialized_end=6895 + _globals['_XDELREQUEST']._serialized_start=6897 + _globals['_XDELREQUEST']._serialized_end=6954 + _globals['_XDELRESPONSE']._serialized_start=6956 + _globals['_XDELRESPONSE']._serialized_end=6970 + _globals['_XTRIMREQUEST']._serialized_start=6972 + _globals['_XTRIMREQUEST']._serialized_end=7035 + _globals['_XTRIMRESPONSE']._serialized_start=7037 + _globals['_XTRIMRESPONSE']._serialized_end=7052 + _globals['_CACHE']._serialized_start=7055 + _globals['_CACHE']._serialized_end=12394 +# @@protoc_insertion_point(module_scope) diff --git a/clients/python/src/supercache/_gen/cache_pb2_grpc.py b/clients/python/src/supercache/_gen/cache_pb2_grpc.py new file mode 100644 index 0000000..4489f31 --- /dev/null +++ b/clients/python/src/supercache/_gen/cache_pb2_grpc.py @@ -0,0 +1,2809 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc +import warnings + +from . import cache_pb2 as cache__pb2 + +GRPC_GENERATED_VERSION = '1.69.0' +GRPC_VERSION = grpc.__version__ +_version_not_supported = False + +try: + from grpc._utilities import first_version_is_lower + _version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION) +except ImportError: + _version_not_supported = True + +if _version_not_supported: + raise RuntimeError( + f'The grpc package installed is at version {GRPC_VERSION},' + + f' but the generated code in cache_pb2_grpc.py depends on' + + f' grpcio>={GRPC_GENERATED_VERSION}.' + + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' + ) + + +class CacheStub(object): + """Cache is the application-facing API (not the peer mesh). + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.Get = channel.unary_unary( + '/supercache.cache.v1.Cache/Get', + request_serializer=cache__pb2.GetRequest.SerializeToString, + response_deserializer=cache__pb2.GetResponse.FromString, + _registered_method=True) + self.Put = channel.unary_unary( + '/supercache.cache.v1.Cache/Put', + request_serializer=cache__pb2.PutRequest.SerializeToString, + response_deserializer=cache__pb2.PutResponse.FromString, + _registered_method=True) + self.PutMany = channel.unary_unary( + '/supercache.cache.v1.Cache/PutMany', + request_serializer=cache__pb2.PutManyRequest.SerializeToString, + response_deserializer=cache__pb2.PutManyResponse.FromString, + _registered_method=True) + self.Delete = channel.unary_unary( + '/supercache.cache.v1.Cache/Delete', + request_serializer=cache__pb2.DeleteRequest.SerializeToString, + response_deserializer=cache__pb2.DeleteResponse.FromString, + _registered_method=True) + self.DeleteMany = channel.unary_unary( + '/supercache.cache.v1.Cache/DeleteMany', + request_serializer=cache__pb2.DeleteManyRequest.SerializeToString, + response_deserializer=cache__pb2.DeleteManyResponse.FromString, + _registered_method=True) + self.BloomAdd = channel.unary_unary( + '/supercache.cache.v1.Cache/BloomAdd', + request_serializer=cache__pb2.BloomAddRequest.SerializeToString, + response_deserializer=cache__pb2.BloomAddResponse.FromString, + _registered_method=True) + self.BloomTest = channel.unary_unary( + '/supercache.cache.v1.Cache/BloomTest', + request_serializer=cache__pb2.BloomTestRequest.SerializeToString, + response_deserializer=cache__pb2.BloomTestResponse.FromString, + _registered_method=True) + self.SetAdd = channel.unary_unary( + '/supercache.cache.v1.Cache/SetAdd', + request_serializer=cache__pb2.SetAddRequest.SerializeToString, + response_deserializer=cache__pb2.SetAddResponse.FromString, + _registered_method=True) + self.SetRemove = channel.unary_unary( + '/supercache.cache.v1.Cache/SetRemove', + request_serializer=cache__pb2.SetRemoveRequest.SerializeToString, + response_deserializer=cache__pb2.SetRemoveResponse.FromString, + _registered_method=True) + self.SetContains = channel.unary_unary( + '/supercache.cache.v1.Cache/SetContains', + request_serializer=cache__pb2.SetContainsRequest.SerializeToString, + response_deserializer=cache__pb2.SetContainsResponse.FromString, + _registered_method=True) + self.SetCard = channel.unary_unary( + '/supercache.cache.v1.Cache/SetCard', + request_serializer=cache__pb2.SetCardRequest.SerializeToString, + response_deserializer=cache__pb2.SetCardResponse.FromString, + _registered_method=True) + self.SetMembers = channel.unary_unary( + '/supercache.cache.v1.Cache/SetMembers', + request_serializer=cache__pb2.SetMembersRequest.SerializeToString, + response_deserializer=cache__pb2.SetMembersResponse.FromString, + _registered_method=True) + self.ZAdd = channel.unary_unary( + '/supercache.cache.v1.Cache/ZAdd', + request_serializer=cache__pb2.ZAddRequest.SerializeToString, + response_deserializer=cache__pb2.ZAddResponse.FromString, + _registered_method=True) + self.ZRem = channel.unary_unary( + '/supercache.cache.v1.Cache/ZRem', + request_serializer=cache__pb2.ZRemRequest.SerializeToString, + response_deserializer=cache__pb2.ZRemResponse.FromString, + _registered_method=True) + self.ZScore = channel.unary_unary( + '/supercache.cache.v1.Cache/ZScore', + request_serializer=cache__pb2.ZScoreRequest.SerializeToString, + response_deserializer=cache__pb2.ZScoreResponse.FromString, + _registered_method=True) + self.ZCard = channel.unary_unary( + '/supercache.cache.v1.Cache/ZCard', + request_serializer=cache__pb2.ZCardRequest.SerializeToString, + response_deserializer=cache__pb2.ZCardResponse.FromString, + _registered_method=True) + self.ZRange = channel.unary_unary( + '/supercache.cache.v1.Cache/ZRange', + request_serializer=cache__pb2.ZRangeRequest.SerializeToString, + response_deserializer=cache__pb2.ZRangeResponse.FromString, + _registered_method=True) + self.ZRangeByScore = channel.unary_unary( + '/supercache.cache.v1.Cache/ZRangeByScore', + request_serializer=cache__pb2.ZRangeByScoreRequest.SerializeToString, + response_deserializer=cache__pb2.ZRangeResponse.FromString, + _registered_method=True) + self.GeoAdd = channel.unary_unary( + '/supercache.cache.v1.Cache/GeoAdd', + request_serializer=cache__pb2.GeoAddRequest.SerializeToString, + response_deserializer=cache__pb2.GeoAddResponse.FromString, + _registered_method=True) + self.GeoRem = channel.unary_unary( + '/supercache.cache.v1.Cache/GeoRem', + request_serializer=cache__pb2.GeoRemRequest.SerializeToString, + response_deserializer=cache__pb2.GeoRemResponse.FromString, + _registered_method=True) + self.GeoPos = channel.unary_unary( + '/supercache.cache.v1.Cache/GeoPos', + request_serializer=cache__pb2.GeoPosRequest.SerializeToString, + response_deserializer=cache__pb2.GeoPosResponse.FromString, + _registered_method=True) + self.GeoCard = channel.unary_unary( + '/supercache.cache.v1.Cache/GeoCard', + request_serializer=cache__pb2.GeoCardRequest.SerializeToString, + response_deserializer=cache__pb2.GeoCardResponse.FromString, + _registered_method=True) + self.GeoDist = channel.unary_unary( + '/supercache.cache.v1.Cache/GeoDist', + request_serializer=cache__pb2.GeoDistRequest.SerializeToString, + response_deserializer=cache__pb2.GeoDistResponse.FromString, + _registered_method=True) + self.GeoRadius = channel.unary_unary( + '/supercache.cache.v1.Cache/GeoRadius', + request_serializer=cache__pb2.GeoRadiusRequest.SerializeToString, + response_deserializer=cache__pb2.GeoRadiusResponse.FromString, + _registered_method=True) + self.LPush = channel.unary_unary( + '/supercache.cache.v1.Cache/LPush', + request_serializer=cache__pb2.LPushRequest.SerializeToString, + response_deserializer=cache__pb2.LPushResponse.FromString, + _registered_method=True) + self.RPush = channel.unary_unary( + '/supercache.cache.v1.Cache/RPush', + request_serializer=cache__pb2.RPushRequest.SerializeToString, + response_deserializer=cache__pb2.RPushResponse.FromString, + _registered_method=True) + self.LPop = channel.unary_unary( + '/supercache.cache.v1.Cache/LPop', + request_serializer=cache__pb2.LPopRequest.SerializeToString, + response_deserializer=cache__pb2.LPopResponse.FromString, + _registered_method=True) + self.RPop = channel.unary_unary( + '/supercache.cache.v1.Cache/RPop', + request_serializer=cache__pb2.RPopRequest.SerializeToString, + response_deserializer=cache__pb2.RPopResponse.FromString, + _registered_method=True) + self.LLen = channel.unary_unary( + '/supercache.cache.v1.Cache/LLen', + request_serializer=cache__pb2.LLenRequest.SerializeToString, + response_deserializer=cache__pb2.LLenResponse.FromString, + _registered_method=True) + self.LIndex = channel.unary_unary( + '/supercache.cache.v1.Cache/LIndex', + request_serializer=cache__pb2.LIndexRequest.SerializeToString, + response_deserializer=cache__pb2.LIndexResponse.FromString, + _registered_method=True) + self.LRange = channel.unary_unary( + '/supercache.cache.v1.Cache/LRange', + request_serializer=cache__pb2.LRangeRequest.SerializeToString, + response_deserializer=cache__pb2.LRangeResponse.FromString, + _registered_method=True) + self.HSet = channel.unary_unary( + '/supercache.cache.v1.Cache/HSet', + request_serializer=cache__pb2.HSetRequest.SerializeToString, + response_deserializer=cache__pb2.HSetResponse.FromString, + _registered_method=True) + self.HGet = channel.unary_unary( + '/supercache.cache.v1.Cache/HGet', + request_serializer=cache__pb2.HGetRequest.SerializeToString, + response_deserializer=cache__pb2.HGetResponse.FromString, + _registered_method=True) + self.HDel = channel.unary_unary( + '/supercache.cache.v1.Cache/HDel', + request_serializer=cache__pb2.HDelRequest.SerializeToString, + response_deserializer=cache__pb2.HDelResponse.FromString, + _registered_method=True) + self.HExists = channel.unary_unary( + '/supercache.cache.v1.Cache/HExists', + request_serializer=cache__pb2.HExistsRequest.SerializeToString, + response_deserializer=cache__pb2.HExistsResponse.FromString, + _registered_method=True) + self.HLen = channel.unary_unary( + '/supercache.cache.v1.Cache/HLen', + request_serializer=cache__pb2.HLenRequest.SerializeToString, + response_deserializer=cache__pb2.HLenResponse.FromString, + _registered_method=True) + self.HGetAll = channel.unary_unary( + '/supercache.cache.v1.Cache/HGetAll', + request_serializer=cache__pb2.HGetAllRequest.SerializeToString, + response_deserializer=cache__pb2.HGetAllResponse.FromString, + _registered_method=True) + self.Incr = channel.unary_unary( + '/supercache.cache.v1.Cache/Incr', + request_serializer=cache__pb2.IncrRequest.SerializeToString, + response_deserializer=cache__pb2.IncrResponse.FromString, + _registered_method=True) + self.CounterGet = channel.unary_unary( + '/supercache.cache.v1.Cache/CounterGet', + request_serializer=cache__pb2.CounterGetRequest.SerializeToString, + response_deserializer=cache__pb2.CounterGetResponse.FromString, + _registered_method=True) + self.JsonSet = channel.unary_unary( + '/supercache.cache.v1.Cache/JsonSet', + request_serializer=cache__pb2.JsonSetRequest.SerializeToString, + response_deserializer=cache__pb2.JsonSetResponse.FromString, + _registered_method=True) + self.JsonGet = channel.unary_unary( + '/supercache.cache.v1.Cache/JsonGet', + request_serializer=cache__pb2.JsonGetRequest.SerializeToString, + response_deserializer=cache__pb2.JsonGetResponse.FromString, + _registered_method=True) + self.JsonDel = channel.unary_unary( + '/supercache.cache.v1.Cache/JsonDel', + request_serializer=cache__pb2.JsonDelRequest.SerializeToString, + response_deserializer=cache__pb2.JsonDelResponse.FromString, + _registered_method=True) + self.BitSet = channel.unary_unary( + '/supercache.cache.v1.Cache/BitSet', + request_serializer=cache__pb2.BitSetRequest.SerializeToString, + response_deserializer=cache__pb2.BitSetResponse.FromString, + _registered_method=True) + self.BitGet = channel.unary_unary( + '/supercache.cache.v1.Cache/BitGet', + request_serializer=cache__pb2.BitGetRequest.SerializeToString, + response_deserializer=cache__pb2.BitGetResponse.FromString, + _registered_method=True) + self.BitCount = channel.unary_unary( + '/supercache.cache.v1.Cache/BitCount', + request_serializer=cache__pb2.BitCountRequest.SerializeToString, + response_deserializer=cache__pb2.BitCountResponse.FromString, + _registered_method=True) + self.BitPos = channel.unary_unary( + '/supercache.cache.v1.Cache/BitPos', + request_serializer=cache__pb2.BitPosRequest.SerializeToString, + response_deserializer=cache__pb2.BitPosResponse.FromString, + _registered_method=True) + self.HLLAdd = channel.unary_unary( + '/supercache.cache.v1.Cache/HLLAdd', + request_serializer=cache__pb2.HLLAddRequest.SerializeToString, + response_deserializer=cache__pb2.HLLAddResponse.FromString, + _registered_method=True) + self.HLLCount = channel.unary_unary( + '/supercache.cache.v1.Cache/HLLCount', + request_serializer=cache__pb2.HLLCountRequest.SerializeToString, + response_deserializer=cache__pb2.HLLCountResponse.FromString, + _registered_method=True) + self.TopKAdd = channel.unary_unary( + '/supercache.cache.v1.Cache/TopKAdd', + request_serializer=cache__pb2.TopKAddRequest.SerializeToString, + response_deserializer=cache__pb2.TopKAddResponse.FromString, + _registered_method=True) + self.TopKList = channel.unary_unary( + '/supercache.cache.v1.Cache/TopKList', + request_serializer=cache__pb2.TopKListRequest.SerializeToString, + response_deserializer=cache__pb2.TopKListResponse.FromString, + _registered_method=True) + self.CMSIncr = channel.unary_unary( + '/supercache.cache.v1.Cache/CMSIncr', + request_serializer=cache__pb2.CMSIncrRequest.SerializeToString, + response_deserializer=cache__pb2.CMSIncrResponse.FromString, + _registered_method=True) + self.CMSQuery = channel.unary_unary( + '/supercache.cache.v1.Cache/CMSQuery', + request_serializer=cache__pb2.CMSQueryRequest.SerializeToString, + response_deserializer=cache__pb2.CMSQueryResponse.FromString, + _registered_method=True) + self.VAdd = channel.unary_unary( + '/supercache.cache.v1.Cache/VAdd', + request_serializer=cache__pb2.VAddRequest.SerializeToString, + response_deserializer=cache__pb2.VAddResponse.FromString, + _registered_method=True) + self.VRem = channel.unary_unary( + '/supercache.cache.v1.Cache/VRem', + request_serializer=cache__pb2.VRemRequest.SerializeToString, + response_deserializer=cache__pb2.VRemResponse.FromString, + _registered_method=True) + self.VSim = channel.unary_unary( + '/supercache.cache.v1.Cache/VSim', + request_serializer=cache__pb2.VSimRequest.SerializeToString, + response_deserializer=cache__pb2.VSimResponse.FromString, + _registered_method=True) + self.VCard = channel.unary_unary( + '/supercache.cache.v1.Cache/VCard', + request_serializer=cache__pb2.VCardRequest.SerializeToString, + response_deserializer=cache__pb2.VCardResponse.FromString, + _registered_method=True) + self.VDim = channel.unary_unary( + '/supercache.cache.v1.Cache/VDim', + request_serializer=cache__pb2.VDimRequest.SerializeToString, + response_deserializer=cache__pb2.VDimResponse.FromString, + _registered_method=True) + self.VEmb = channel.unary_unary( + '/supercache.cache.v1.Cache/VEmb', + request_serializer=cache__pb2.VEmbRequest.SerializeToString, + response_deserializer=cache__pb2.VEmbResponse.FromString, + _registered_method=True) + self.XAdd = channel.unary_unary( + '/supercache.cache.v1.Cache/XAdd', + request_serializer=cache__pb2.XAddRequest.SerializeToString, + response_deserializer=cache__pb2.XAddResponse.FromString, + _registered_method=True) + self.XRange = channel.unary_unary( + '/supercache.cache.v1.Cache/XRange', + request_serializer=cache__pb2.XRangeRequest.SerializeToString, + response_deserializer=cache__pb2.XRangeResponse.FromString, + _registered_method=True) + self.XRevRange = channel.unary_unary( + '/supercache.cache.v1.Cache/XRevRange', + request_serializer=cache__pb2.XRevRangeRequest.SerializeToString, + response_deserializer=cache__pb2.XRangeResponse.FromString, + _registered_method=True) + self.XLen = channel.unary_unary( + '/supercache.cache.v1.Cache/XLen', + request_serializer=cache__pb2.XLenRequest.SerializeToString, + response_deserializer=cache__pb2.XLenResponse.FromString, + _registered_method=True) + self.XDel = channel.unary_unary( + '/supercache.cache.v1.Cache/XDel', + request_serializer=cache__pb2.XDelRequest.SerializeToString, + response_deserializer=cache__pb2.XDelResponse.FromString, + _registered_method=True) + self.XTrim = channel.unary_unary( + '/supercache.cache.v1.Cache/XTrim', + request_serializer=cache__pb2.XTrimRequest.SerializeToString, + response_deserializer=cache__pb2.XTrimResponse.FromString, + _registered_method=True) + + +class CacheServicer(object): + """Cache is the application-facing API (not the peer mesh). + """ + + def Get(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Put(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def PutMany(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Delete(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def DeleteMany(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def BloomAdd(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def BloomTest(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def SetAdd(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def SetRemove(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def SetContains(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def SetCard(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def SetMembers(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ZAdd(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ZRem(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ZScore(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ZCard(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ZRange(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ZRangeByScore(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GeoAdd(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GeoRem(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GeoPos(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GeoCard(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GeoDist(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GeoRadius(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def LPush(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def RPush(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def LPop(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def RPop(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def LLen(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def LIndex(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def LRange(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def HSet(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def HGet(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def HDel(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def HExists(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def HLen(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def HGetAll(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def Incr(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CounterGet(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def JsonSet(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def JsonGet(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def JsonDel(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def BitSet(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def BitGet(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def BitCount(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def BitPos(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def HLLAdd(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def HLLCount(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def TopKAdd(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def TopKList(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CMSIncr(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CMSQuery(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def VAdd(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def VRem(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def VSim(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def VCard(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def VDim(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def VEmb(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def XAdd(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def XRange(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def XRevRange(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def XLen(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def XDel(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def XTrim(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_CacheServicer_to_server(servicer, server): + rpc_method_handlers = { + 'Get': grpc.unary_unary_rpc_method_handler( + servicer.Get, + request_deserializer=cache__pb2.GetRequest.FromString, + response_serializer=cache__pb2.GetResponse.SerializeToString, + ), + 'Put': grpc.unary_unary_rpc_method_handler( + servicer.Put, + request_deserializer=cache__pb2.PutRequest.FromString, + response_serializer=cache__pb2.PutResponse.SerializeToString, + ), + 'PutMany': grpc.unary_unary_rpc_method_handler( + servicer.PutMany, + request_deserializer=cache__pb2.PutManyRequest.FromString, + response_serializer=cache__pb2.PutManyResponse.SerializeToString, + ), + 'Delete': grpc.unary_unary_rpc_method_handler( + servicer.Delete, + request_deserializer=cache__pb2.DeleteRequest.FromString, + response_serializer=cache__pb2.DeleteResponse.SerializeToString, + ), + 'DeleteMany': grpc.unary_unary_rpc_method_handler( + servicer.DeleteMany, + request_deserializer=cache__pb2.DeleteManyRequest.FromString, + response_serializer=cache__pb2.DeleteManyResponse.SerializeToString, + ), + 'BloomAdd': grpc.unary_unary_rpc_method_handler( + servicer.BloomAdd, + request_deserializer=cache__pb2.BloomAddRequest.FromString, + response_serializer=cache__pb2.BloomAddResponse.SerializeToString, + ), + 'BloomTest': grpc.unary_unary_rpc_method_handler( + servicer.BloomTest, + request_deserializer=cache__pb2.BloomTestRequest.FromString, + response_serializer=cache__pb2.BloomTestResponse.SerializeToString, + ), + 'SetAdd': grpc.unary_unary_rpc_method_handler( + servicer.SetAdd, + request_deserializer=cache__pb2.SetAddRequest.FromString, + response_serializer=cache__pb2.SetAddResponse.SerializeToString, + ), + 'SetRemove': grpc.unary_unary_rpc_method_handler( + servicer.SetRemove, + request_deserializer=cache__pb2.SetRemoveRequest.FromString, + response_serializer=cache__pb2.SetRemoveResponse.SerializeToString, + ), + 'SetContains': grpc.unary_unary_rpc_method_handler( + servicer.SetContains, + request_deserializer=cache__pb2.SetContainsRequest.FromString, + response_serializer=cache__pb2.SetContainsResponse.SerializeToString, + ), + 'SetCard': grpc.unary_unary_rpc_method_handler( + servicer.SetCard, + request_deserializer=cache__pb2.SetCardRequest.FromString, + response_serializer=cache__pb2.SetCardResponse.SerializeToString, + ), + 'SetMembers': grpc.unary_unary_rpc_method_handler( + servicer.SetMembers, + request_deserializer=cache__pb2.SetMembersRequest.FromString, + response_serializer=cache__pb2.SetMembersResponse.SerializeToString, + ), + 'ZAdd': grpc.unary_unary_rpc_method_handler( + servicer.ZAdd, + request_deserializer=cache__pb2.ZAddRequest.FromString, + response_serializer=cache__pb2.ZAddResponse.SerializeToString, + ), + 'ZRem': grpc.unary_unary_rpc_method_handler( + servicer.ZRem, + request_deserializer=cache__pb2.ZRemRequest.FromString, + response_serializer=cache__pb2.ZRemResponse.SerializeToString, + ), + 'ZScore': grpc.unary_unary_rpc_method_handler( + servicer.ZScore, + request_deserializer=cache__pb2.ZScoreRequest.FromString, + response_serializer=cache__pb2.ZScoreResponse.SerializeToString, + ), + 'ZCard': grpc.unary_unary_rpc_method_handler( + servicer.ZCard, + request_deserializer=cache__pb2.ZCardRequest.FromString, + response_serializer=cache__pb2.ZCardResponse.SerializeToString, + ), + 'ZRange': grpc.unary_unary_rpc_method_handler( + servicer.ZRange, + request_deserializer=cache__pb2.ZRangeRequest.FromString, + response_serializer=cache__pb2.ZRangeResponse.SerializeToString, + ), + 'ZRangeByScore': grpc.unary_unary_rpc_method_handler( + servicer.ZRangeByScore, + request_deserializer=cache__pb2.ZRangeByScoreRequest.FromString, + response_serializer=cache__pb2.ZRangeResponse.SerializeToString, + ), + 'GeoAdd': grpc.unary_unary_rpc_method_handler( + servicer.GeoAdd, + request_deserializer=cache__pb2.GeoAddRequest.FromString, + response_serializer=cache__pb2.GeoAddResponse.SerializeToString, + ), + 'GeoRem': grpc.unary_unary_rpc_method_handler( + servicer.GeoRem, + request_deserializer=cache__pb2.GeoRemRequest.FromString, + response_serializer=cache__pb2.GeoRemResponse.SerializeToString, + ), + 'GeoPos': grpc.unary_unary_rpc_method_handler( + servicer.GeoPos, + request_deserializer=cache__pb2.GeoPosRequest.FromString, + response_serializer=cache__pb2.GeoPosResponse.SerializeToString, + ), + 'GeoCard': grpc.unary_unary_rpc_method_handler( + servicer.GeoCard, + request_deserializer=cache__pb2.GeoCardRequest.FromString, + response_serializer=cache__pb2.GeoCardResponse.SerializeToString, + ), + 'GeoDist': grpc.unary_unary_rpc_method_handler( + servicer.GeoDist, + request_deserializer=cache__pb2.GeoDistRequest.FromString, + response_serializer=cache__pb2.GeoDistResponse.SerializeToString, + ), + 'GeoRadius': grpc.unary_unary_rpc_method_handler( + servicer.GeoRadius, + request_deserializer=cache__pb2.GeoRadiusRequest.FromString, + response_serializer=cache__pb2.GeoRadiusResponse.SerializeToString, + ), + 'LPush': grpc.unary_unary_rpc_method_handler( + servicer.LPush, + request_deserializer=cache__pb2.LPushRequest.FromString, + response_serializer=cache__pb2.LPushResponse.SerializeToString, + ), + 'RPush': grpc.unary_unary_rpc_method_handler( + servicer.RPush, + request_deserializer=cache__pb2.RPushRequest.FromString, + response_serializer=cache__pb2.RPushResponse.SerializeToString, + ), + 'LPop': grpc.unary_unary_rpc_method_handler( + servicer.LPop, + request_deserializer=cache__pb2.LPopRequest.FromString, + response_serializer=cache__pb2.LPopResponse.SerializeToString, + ), + 'RPop': grpc.unary_unary_rpc_method_handler( + servicer.RPop, + request_deserializer=cache__pb2.RPopRequest.FromString, + response_serializer=cache__pb2.RPopResponse.SerializeToString, + ), + 'LLen': grpc.unary_unary_rpc_method_handler( + servicer.LLen, + request_deserializer=cache__pb2.LLenRequest.FromString, + response_serializer=cache__pb2.LLenResponse.SerializeToString, + ), + 'LIndex': grpc.unary_unary_rpc_method_handler( + servicer.LIndex, + request_deserializer=cache__pb2.LIndexRequest.FromString, + response_serializer=cache__pb2.LIndexResponse.SerializeToString, + ), + 'LRange': grpc.unary_unary_rpc_method_handler( + servicer.LRange, + request_deserializer=cache__pb2.LRangeRequest.FromString, + response_serializer=cache__pb2.LRangeResponse.SerializeToString, + ), + 'HSet': grpc.unary_unary_rpc_method_handler( + servicer.HSet, + request_deserializer=cache__pb2.HSetRequest.FromString, + response_serializer=cache__pb2.HSetResponse.SerializeToString, + ), + 'HGet': grpc.unary_unary_rpc_method_handler( + servicer.HGet, + request_deserializer=cache__pb2.HGetRequest.FromString, + response_serializer=cache__pb2.HGetResponse.SerializeToString, + ), + 'HDel': grpc.unary_unary_rpc_method_handler( + servicer.HDel, + request_deserializer=cache__pb2.HDelRequest.FromString, + response_serializer=cache__pb2.HDelResponse.SerializeToString, + ), + 'HExists': grpc.unary_unary_rpc_method_handler( + servicer.HExists, + request_deserializer=cache__pb2.HExistsRequest.FromString, + response_serializer=cache__pb2.HExistsResponse.SerializeToString, + ), + 'HLen': grpc.unary_unary_rpc_method_handler( + servicer.HLen, + request_deserializer=cache__pb2.HLenRequest.FromString, + response_serializer=cache__pb2.HLenResponse.SerializeToString, + ), + 'HGetAll': grpc.unary_unary_rpc_method_handler( + servicer.HGetAll, + request_deserializer=cache__pb2.HGetAllRequest.FromString, + response_serializer=cache__pb2.HGetAllResponse.SerializeToString, + ), + 'Incr': grpc.unary_unary_rpc_method_handler( + servicer.Incr, + request_deserializer=cache__pb2.IncrRequest.FromString, + response_serializer=cache__pb2.IncrResponse.SerializeToString, + ), + 'CounterGet': grpc.unary_unary_rpc_method_handler( + servicer.CounterGet, + request_deserializer=cache__pb2.CounterGetRequest.FromString, + response_serializer=cache__pb2.CounterGetResponse.SerializeToString, + ), + 'JsonSet': grpc.unary_unary_rpc_method_handler( + servicer.JsonSet, + request_deserializer=cache__pb2.JsonSetRequest.FromString, + response_serializer=cache__pb2.JsonSetResponse.SerializeToString, + ), + 'JsonGet': grpc.unary_unary_rpc_method_handler( + servicer.JsonGet, + request_deserializer=cache__pb2.JsonGetRequest.FromString, + response_serializer=cache__pb2.JsonGetResponse.SerializeToString, + ), + 'JsonDel': grpc.unary_unary_rpc_method_handler( + servicer.JsonDel, + request_deserializer=cache__pb2.JsonDelRequest.FromString, + response_serializer=cache__pb2.JsonDelResponse.SerializeToString, + ), + 'BitSet': grpc.unary_unary_rpc_method_handler( + servicer.BitSet, + request_deserializer=cache__pb2.BitSetRequest.FromString, + response_serializer=cache__pb2.BitSetResponse.SerializeToString, + ), + 'BitGet': grpc.unary_unary_rpc_method_handler( + servicer.BitGet, + request_deserializer=cache__pb2.BitGetRequest.FromString, + response_serializer=cache__pb2.BitGetResponse.SerializeToString, + ), + 'BitCount': grpc.unary_unary_rpc_method_handler( + servicer.BitCount, + request_deserializer=cache__pb2.BitCountRequest.FromString, + response_serializer=cache__pb2.BitCountResponse.SerializeToString, + ), + 'BitPos': grpc.unary_unary_rpc_method_handler( + servicer.BitPos, + request_deserializer=cache__pb2.BitPosRequest.FromString, + response_serializer=cache__pb2.BitPosResponse.SerializeToString, + ), + 'HLLAdd': grpc.unary_unary_rpc_method_handler( + servicer.HLLAdd, + request_deserializer=cache__pb2.HLLAddRequest.FromString, + response_serializer=cache__pb2.HLLAddResponse.SerializeToString, + ), + 'HLLCount': grpc.unary_unary_rpc_method_handler( + servicer.HLLCount, + request_deserializer=cache__pb2.HLLCountRequest.FromString, + response_serializer=cache__pb2.HLLCountResponse.SerializeToString, + ), + 'TopKAdd': grpc.unary_unary_rpc_method_handler( + servicer.TopKAdd, + request_deserializer=cache__pb2.TopKAddRequest.FromString, + response_serializer=cache__pb2.TopKAddResponse.SerializeToString, + ), + 'TopKList': grpc.unary_unary_rpc_method_handler( + servicer.TopKList, + request_deserializer=cache__pb2.TopKListRequest.FromString, + response_serializer=cache__pb2.TopKListResponse.SerializeToString, + ), + 'CMSIncr': grpc.unary_unary_rpc_method_handler( + servicer.CMSIncr, + request_deserializer=cache__pb2.CMSIncrRequest.FromString, + response_serializer=cache__pb2.CMSIncrResponse.SerializeToString, + ), + 'CMSQuery': grpc.unary_unary_rpc_method_handler( + servicer.CMSQuery, + request_deserializer=cache__pb2.CMSQueryRequest.FromString, + response_serializer=cache__pb2.CMSQueryResponse.SerializeToString, + ), + 'VAdd': grpc.unary_unary_rpc_method_handler( + servicer.VAdd, + request_deserializer=cache__pb2.VAddRequest.FromString, + response_serializer=cache__pb2.VAddResponse.SerializeToString, + ), + 'VRem': grpc.unary_unary_rpc_method_handler( + servicer.VRem, + request_deserializer=cache__pb2.VRemRequest.FromString, + response_serializer=cache__pb2.VRemResponse.SerializeToString, + ), + 'VSim': grpc.unary_unary_rpc_method_handler( + servicer.VSim, + request_deserializer=cache__pb2.VSimRequest.FromString, + response_serializer=cache__pb2.VSimResponse.SerializeToString, + ), + 'VCard': grpc.unary_unary_rpc_method_handler( + servicer.VCard, + request_deserializer=cache__pb2.VCardRequest.FromString, + response_serializer=cache__pb2.VCardResponse.SerializeToString, + ), + 'VDim': grpc.unary_unary_rpc_method_handler( + servicer.VDim, + request_deserializer=cache__pb2.VDimRequest.FromString, + response_serializer=cache__pb2.VDimResponse.SerializeToString, + ), + 'VEmb': grpc.unary_unary_rpc_method_handler( + servicer.VEmb, + request_deserializer=cache__pb2.VEmbRequest.FromString, + response_serializer=cache__pb2.VEmbResponse.SerializeToString, + ), + 'XAdd': grpc.unary_unary_rpc_method_handler( + servicer.XAdd, + request_deserializer=cache__pb2.XAddRequest.FromString, + response_serializer=cache__pb2.XAddResponse.SerializeToString, + ), + 'XRange': grpc.unary_unary_rpc_method_handler( + servicer.XRange, + request_deserializer=cache__pb2.XRangeRequest.FromString, + response_serializer=cache__pb2.XRangeResponse.SerializeToString, + ), + 'XRevRange': grpc.unary_unary_rpc_method_handler( + servicer.XRevRange, + request_deserializer=cache__pb2.XRevRangeRequest.FromString, + response_serializer=cache__pb2.XRangeResponse.SerializeToString, + ), + 'XLen': grpc.unary_unary_rpc_method_handler( + servicer.XLen, + request_deserializer=cache__pb2.XLenRequest.FromString, + response_serializer=cache__pb2.XLenResponse.SerializeToString, + ), + 'XDel': grpc.unary_unary_rpc_method_handler( + servicer.XDel, + request_deserializer=cache__pb2.XDelRequest.FromString, + response_serializer=cache__pb2.XDelResponse.SerializeToString, + ), + 'XTrim': grpc.unary_unary_rpc_method_handler( + servicer.XTrim, + request_deserializer=cache__pb2.XTrimRequest.FromString, + response_serializer=cache__pb2.XTrimResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'supercache.cache.v1.Cache', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('supercache.cache.v1.Cache', rpc_method_handlers) + + + # This class is part of an EXPERIMENTAL API. +class Cache(object): + """Cache is the application-facing API (not the peer mesh). + """ + + @staticmethod + def Get(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/Get', + cache__pb2.GetRequest.SerializeToString, + cache__pb2.GetResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Put(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/Put', + cache__pb2.PutRequest.SerializeToString, + cache__pb2.PutResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def PutMany(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/PutMany', + cache__pb2.PutManyRequest.SerializeToString, + cache__pb2.PutManyResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Delete(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/Delete', + cache__pb2.DeleteRequest.SerializeToString, + cache__pb2.DeleteResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def DeleteMany(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/DeleteMany', + cache__pb2.DeleteManyRequest.SerializeToString, + cache__pb2.DeleteManyResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def BloomAdd(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/BloomAdd', + cache__pb2.BloomAddRequest.SerializeToString, + cache__pb2.BloomAddResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def BloomTest(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/BloomTest', + cache__pb2.BloomTestRequest.SerializeToString, + cache__pb2.BloomTestResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def SetAdd(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/SetAdd', + cache__pb2.SetAddRequest.SerializeToString, + cache__pb2.SetAddResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def SetRemove(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/SetRemove', + cache__pb2.SetRemoveRequest.SerializeToString, + cache__pb2.SetRemoveResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def SetContains(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/SetContains', + cache__pb2.SetContainsRequest.SerializeToString, + cache__pb2.SetContainsResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def SetCard(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/SetCard', + cache__pb2.SetCardRequest.SerializeToString, + cache__pb2.SetCardResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def SetMembers(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/SetMembers', + cache__pb2.SetMembersRequest.SerializeToString, + cache__pb2.SetMembersResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def ZAdd(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/ZAdd', + cache__pb2.ZAddRequest.SerializeToString, + cache__pb2.ZAddResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def ZRem(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/ZRem', + cache__pb2.ZRemRequest.SerializeToString, + cache__pb2.ZRemResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def ZScore(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/ZScore', + cache__pb2.ZScoreRequest.SerializeToString, + cache__pb2.ZScoreResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def ZCard(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/ZCard', + cache__pb2.ZCardRequest.SerializeToString, + cache__pb2.ZCardResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def ZRange(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/ZRange', + cache__pb2.ZRangeRequest.SerializeToString, + cache__pb2.ZRangeResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def ZRangeByScore(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/ZRangeByScore', + cache__pb2.ZRangeByScoreRequest.SerializeToString, + cache__pb2.ZRangeResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GeoAdd(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/GeoAdd', + cache__pb2.GeoAddRequest.SerializeToString, + cache__pb2.GeoAddResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GeoRem(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/GeoRem', + cache__pb2.GeoRemRequest.SerializeToString, + cache__pb2.GeoRemResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GeoPos(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/GeoPos', + cache__pb2.GeoPosRequest.SerializeToString, + cache__pb2.GeoPosResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GeoCard(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/GeoCard', + cache__pb2.GeoCardRequest.SerializeToString, + cache__pb2.GeoCardResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GeoDist(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/GeoDist', + cache__pb2.GeoDistRequest.SerializeToString, + cache__pb2.GeoDistResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def GeoRadius(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/GeoRadius', + cache__pb2.GeoRadiusRequest.SerializeToString, + cache__pb2.GeoRadiusResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def LPush(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/LPush', + cache__pb2.LPushRequest.SerializeToString, + cache__pb2.LPushResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def RPush(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/RPush', + cache__pb2.RPushRequest.SerializeToString, + cache__pb2.RPushResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def LPop(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/LPop', + cache__pb2.LPopRequest.SerializeToString, + cache__pb2.LPopResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def RPop(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/RPop', + cache__pb2.RPopRequest.SerializeToString, + cache__pb2.RPopResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def LLen(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/LLen', + cache__pb2.LLenRequest.SerializeToString, + cache__pb2.LLenResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def LIndex(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/LIndex', + cache__pb2.LIndexRequest.SerializeToString, + cache__pb2.LIndexResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def LRange(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/LRange', + cache__pb2.LRangeRequest.SerializeToString, + cache__pb2.LRangeResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def HSet(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/HSet', + cache__pb2.HSetRequest.SerializeToString, + cache__pb2.HSetResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def HGet(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/HGet', + cache__pb2.HGetRequest.SerializeToString, + cache__pb2.HGetResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def HDel(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/HDel', + cache__pb2.HDelRequest.SerializeToString, + cache__pb2.HDelResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def HExists(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/HExists', + cache__pb2.HExistsRequest.SerializeToString, + cache__pb2.HExistsResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def HLen(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/HLen', + cache__pb2.HLenRequest.SerializeToString, + cache__pb2.HLenResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def HGetAll(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/HGetAll', + cache__pb2.HGetAllRequest.SerializeToString, + cache__pb2.HGetAllResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def Incr(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/Incr', + cache__pb2.IncrRequest.SerializeToString, + cache__pb2.IncrResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def CounterGet(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/CounterGet', + cache__pb2.CounterGetRequest.SerializeToString, + cache__pb2.CounterGetResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def JsonSet(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/JsonSet', + cache__pb2.JsonSetRequest.SerializeToString, + cache__pb2.JsonSetResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def JsonGet(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/JsonGet', + cache__pb2.JsonGetRequest.SerializeToString, + cache__pb2.JsonGetResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def JsonDel(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/JsonDel', + cache__pb2.JsonDelRequest.SerializeToString, + cache__pb2.JsonDelResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def BitSet(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/BitSet', + cache__pb2.BitSetRequest.SerializeToString, + cache__pb2.BitSetResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def BitGet(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/BitGet', + cache__pb2.BitGetRequest.SerializeToString, + cache__pb2.BitGetResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def BitCount(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/BitCount', + cache__pb2.BitCountRequest.SerializeToString, + cache__pb2.BitCountResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def BitPos(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/BitPos', + cache__pb2.BitPosRequest.SerializeToString, + cache__pb2.BitPosResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def HLLAdd(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/HLLAdd', + cache__pb2.HLLAddRequest.SerializeToString, + cache__pb2.HLLAddResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def HLLCount(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/HLLCount', + cache__pb2.HLLCountRequest.SerializeToString, + cache__pb2.HLLCountResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def TopKAdd(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/TopKAdd', + cache__pb2.TopKAddRequest.SerializeToString, + cache__pb2.TopKAddResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def TopKList(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/TopKList', + cache__pb2.TopKListRequest.SerializeToString, + cache__pb2.TopKListResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def CMSIncr(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/CMSIncr', + cache__pb2.CMSIncrRequest.SerializeToString, + cache__pb2.CMSIncrResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def CMSQuery(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/CMSQuery', + cache__pb2.CMSQueryRequest.SerializeToString, + cache__pb2.CMSQueryResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def VAdd(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/VAdd', + cache__pb2.VAddRequest.SerializeToString, + cache__pb2.VAddResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def VRem(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/VRem', + cache__pb2.VRemRequest.SerializeToString, + cache__pb2.VRemResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def VSim(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/VSim', + cache__pb2.VSimRequest.SerializeToString, + cache__pb2.VSimResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def VCard(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/VCard', + cache__pb2.VCardRequest.SerializeToString, + cache__pb2.VCardResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def VDim(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/VDim', + cache__pb2.VDimRequest.SerializeToString, + cache__pb2.VDimResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def VEmb(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/VEmb', + cache__pb2.VEmbRequest.SerializeToString, + cache__pb2.VEmbResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def XAdd(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/XAdd', + cache__pb2.XAddRequest.SerializeToString, + cache__pb2.XAddResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def XRange(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/XRange', + cache__pb2.XRangeRequest.SerializeToString, + cache__pb2.XRangeResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def XRevRange(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/XRevRange', + cache__pb2.XRevRangeRequest.SerializeToString, + cache__pb2.XRangeResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def XLen(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/XLen', + cache__pb2.XLenRequest.SerializeToString, + cache__pb2.XLenResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def XDel(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/XDel', + cache__pb2.XDelRequest.SerializeToString, + cache__pb2.XDelResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) + + @staticmethod + def XTrim(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/supercache.cache.v1.Cache/XTrim', + cache__pb2.XTrimRequest.SerializeToString, + cache__pb2.XTrimResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/clients/python/src/supercache/client.py b/clients/python/src/supercache/client.py new file mode 100644 index 0000000..661bea0 --- /dev/null +++ b/clients/python/src/supercache/client.py @@ -0,0 +1,170 @@ +"""Sync Cache client. Semantics match pkg/client in the Go module. + +Return types live in supercache.types. Each keyspace mode lives in supercache.ops. +This file is the connection and the KV calls. +""" + +from __future__ import annotations + +from datetime import timedelta +from pathlib import Path +from typing import Sequence + +import grpc + +from supercache._gen import cache_pb2 as pb +from supercache._gen import cache_pb2_grpc as pb_grpc +from supercache.errors import NotFound, StatusError +from supercache.ops.bitmap import BitmapOps +from supercache.ops.bloom import BloomOps +from supercache.ops.cms import CMSOps +from supercache.ops.counter import CounterOps +from supercache.ops.geo import GeoOps +from supercache.ops.hash import HashOps +from supercache.ops.hll import HLLOps +from supercache.ops.json import JsonOps +from supercache.ops.list import ListOps +from supercache.ops.set import SetOps +from supercache.ops.stream import StreamOps +from supercache.ops.topk import TopKOps +from supercache.ops.vecset import VecSetOps +from supercache.ops.zset import ZSetOps +from supercache.wire import as_bytes, raise_key_errors, raise_peer_failures, ttl_fields + + +class Client( + BloomOps, + SetOps, + ZSetOps, + GeoOps, + ListOps, + HashOps, + CounterOps, + JsonOps, + BitmapOps, + HLLOps, + TopKOps, + CMSOps, + VecSetOps, + StreamOps, +): + """One channel to a cache node. Close it when finished.""" + + def __init__(self, channel: grpc.Channel, timeout: timedelta | None = None) -> None: + self._channel = channel + self._stub = pb_grpc.CacheStub(channel) + self.timeout = timeout + self._closed = False + + def close(self) -> None: + if self._closed: + return + self._closed = True + self._channel.close() + + def wait_ready(self, timeout_s: float) -> None: + grpc.channel_ready_future(self._channel).result(timeout=timeout_s) + + def _seconds(self, timeout: timedelta | None) -> float | None: + chosen = self.timeout if timeout is None else timeout + if chosen is None: + return None + return chosen.total_seconds() + + def _call(self, method, request, timeout: timedelta | None): + kwargs = {} + seconds = self._seconds(timeout) + if seconds is not None: + kwargs["timeout"] = seconds + try: + return method(request, **kwargs) + except grpc.RpcError as exc: + code = exc.code() + name = code.name if code is not None else "UNKNOWN" + raise StatusError(name, exc.details() or "") from exc + + def get(self, keyspace: str, key: str, *, timeout: timedelta | None = None) -> bytes: + request = pb.GetRequest(keyspace=keyspace, key=key) + response = self._call(self._stub.Get, request, timeout) + if not response.found: + raise NotFound(f"{keyspace}/{key}") + return response.value + + def put( + self, + keyspace: str, + key: str, + value: bytes, + *, + ttl: timedelta | None = None, + timeout: timedelta | None = None, + ) -> None: + nanos, set_ = ttl_fields(ttl) + request = pb.PutRequest( + keyspace=keyspace, + key=key, + value=as_bytes(value, "value"), + ttl_nanos=nanos, + ttl_set=set_, + ) + self._call(self._stub.Put, request, timeout) + + def put_many( + self, + keyspace: str, + items: Sequence[tuple[str, bytes]], + *, + ttl: timedelta | None = None, + timeout: timedelta | None = None, + ) -> None: + nanos, set_ = ttl_fields(ttl) + request = pb.PutManyRequest( + keyspace=keyspace, + items=[pb.KV(key=key, value=as_bytes(value, "value")) for key, value in items], + ttl_nanos=nanos, + ttl_set=set_, + ) + response = self._call(self._stub.PutMany, request, timeout) + raise_key_errors(response.errors) + + def delete(self, keyspace: str, key: str, *, timeout: timedelta | None = None) -> None: + request = pb.DeleteRequest(keyspace=keyspace, key=key) + response = self._call(self._stub.Delete, request, timeout) + raise_peer_failures(response.peer_failures) + + def delete_many(self, keyspace: str, keys: Sequence[str], *, timeout: timedelta | None = None) -> None: + request = pb.DeleteManyRequest(keyspace=keyspace, keys=list(keys)) + response = self._call(self._stub.DeleteMany, request, timeout) + raise_key_errors(response.errors) + + +def dial(addr: str, *, timeout: timedelta | None = None) -> Client: + """Plaintext dial. For local development and tests.""" + return Client(grpc.insecure_channel(addr), timeout) + + +def dial_tls( + addr: str, + ca_file: str, + server_name: str, + client_cert: str | None = None, + client_key: str | None = None, + *, + timeout: timedelta | None = None, +) -> Client: + """TLS dial. server_name is required (the cert name, not the IP).""" + if not server_name: + raise ValueError("server_name is required") + if bool(client_cert) != bool(client_key): + raise ValueError("client_cert and client_key must both be set") + root = Path(ca_file).read_bytes() + if client_cert and client_key: + creds = grpc.ssl_channel_credentials( + root_certificates=root, + private_key=Path(client_key).read_bytes(), + certificate_chain=Path(client_cert).read_bytes(), + ) + else: + creds = grpc.ssl_channel_credentials(root_certificates=root) + channel = grpc.secure_channel(addr, creds, (("grpc.ssl_target_name_override", server_name),)) + return Client(channel, timeout) diff --git a/clients/python/src/supercache/errors.py b/clients/python/src/supercache/errors.py new file mode 100644 index 0000000..80166d8 --- /dev/null +++ b/clients/python/src/supercache/errors.py @@ -0,0 +1,69 @@ +"""Errors raised by the SuperCache client. + +NotFound is only a Get that returned found=false. A gRPC status, including +NOT_FOUND for a missing keyspace, is StatusError. +""" + +from __future__ import annotations + +from dataclasses import dataclass + + +class NotFound(Exception): + """Get returned found=false (missing, negative cache, or tombstone).""" + + +class StatusError(Exception): + """A gRPC status. code is the name, for example NOT_FOUND or UNAVAILABLE.""" + + def __init__(self, code: str, message: str) -> None: + self.code = code + self.message = message + super().__init__(f"{code}: {message}") + + +@dataclass(frozen=True) +class PeerFailure: + peer_id: str + message: str + + +class PeerFailures(Exception): + """Delete succeeded on the wire and reported replica failures.""" + + def __init__(self, failures: list[PeerFailure]) -> None: + self.failures = failures + super().__init__(f"{len(failures)} peer failure(s)") + + +@dataclass(frozen=True) +class KeyErrorItem: + key: str + message: str + peer_failures: list[PeerFailure] + + +class KeyErrors(Exception): + """PutMany or DeleteMany succeeded on the wire and reported per-key failures.""" + + def __init__(self, errors: list[KeyErrorItem]) -> None: + self.errors = errors + super().__init__(f"{len(errors)} key error(s)") + + +def is_transport(err: BaseException) -> bool: + """True for a dead connection. A call deadline is not transport: the RPC may have landed.""" + if not isinstance(err, StatusError): + return False + if err.code == "UNAVAILABLE": + return True + msg = err.message.lower() + needles = ( + "connection refused", + "connection reset", + "broken pipe", + "socket hang up", + "econnrefused", + "econnreset", + ) + return any(n in msg for n in needles) diff --git a/clients/python/src/supercache/ops/__init__.py b/clients/python/src/supercache/ops/__init__.py new file mode 100644 index 0000000..380c246 --- /dev/null +++ b/clients/python/src/supercache/ops/__init__.py @@ -0,0 +1 @@ +"""Cache verbs, one module per mode. Client subclasses these.""" diff --git a/clients/python/src/supercache/ops/bitmap.py b/clients/python/src/supercache/ops/bitmap.py new file mode 100644 index 0000000..8e654a0 --- /dev/null +++ b/clients/python/src/supercache/ops/bitmap.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.types import BitPos, BitValue + + +class BitmapOps: + def bit_set( + self, + keyspace: str, + name: str, + offset: int, + bit: bool, + *, + timeout: timedelta | None = None, + ) -> None: + request = pb.BitSetRequest(keyspace=keyspace, name=name, offset=offset, bit=bit) + self._call(self._stub.BitSet, request, timeout) + + def bit_get(self, keyspace: str, name: str, offset: int, *, timeout: timedelta | None = None) -> BitValue: + request = pb.BitGetRequest(keyspace=keyspace, name=name, offset=offset) + response = self._call(self._stub.BitGet, request, timeout) + return BitValue(bool(response.bit), bool(response.present)) + + def bit_count( + self, + keyspace: str, + name: str, + start: int, + end: int, + *, + timeout: timedelta | None = None, + ) -> int: + request = pb.BitCountRequest(keyspace=keyspace, name=name, start=start, end=end) + response = self._call(self._stub.BitCount, request, timeout) + return int(response.count) + + def bit_pos( + self, + keyspace: str, + name: str, + bit: bool, + start: int, + end: int, + *, + timeout: timedelta | None = None, + ) -> BitPos: + request = pb.BitPosRequest(keyspace=keyspace, name=name, bit=bit, start=start, end=end) + response = self._call(self._stub.BitPos, request, timeout) + return BitPos(int(response.pos), bool(response.found)) diff --git a/clients/python/src/supercache/ops/bloom.py b/clients/python/src/supercache/ops/bloom.py new file mode 100644 index 0000000..288e4ff --- /dev/null +++ b/clients/python/src/supercache/ops/bloom.py @@ -0,0 +1,25 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.wire import as_bytes + + +class BloomOps: + def bloom_add(self, keyspace: str, name: str, item: bytes, *, timeout: timedelta | None = None) -> None: + request = pb.BloomAddRequest( + keyspace=keyspace, + name=name, + item=as_bytes(item, "item"), + ) + self._call(self._stub.BloomAdd, request, timeout) + + def bloom_test(self, keyspace: str, name: str, item: bytes, *, timeout: timedelta | None = None) -> bool: + request = pb.BloomTestRequest( + keyspace=keyspace, + name=name, + item=as_bytes(item, "item"), + ) + response = self._call(self._stub.BloomTest, request, timeout) + return bool(response.maybe) diff --git a/clients/python/src/supercache/ops/cms.py b/clients/python/src/supercache/ops/cms.py new file mode 100644 index 0000000..a2fa942 --- /dev/null +++ b/clients/python/src/supercache/ops/cms.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.types import Present +from supercache.wire import as_bytes + + +class CMSOps: + def cms_incr( + self, + keyspace: str, + name: str, + item: bytes, + n: int, + *, + timeout: timedelta | None = None, + ) -> None: + request = pb.CMSIncrRequest( + keyspace=keyspace, + name=name, + item=as_bytes(item, "item"), + n=n, + ) + self._call(self._stub.CMSIncr, request, timeout) + + def cms_query(self, keyspace: str, name: str, item: bytes, *, timeout: timedelta | None = None) -> Present: + request = pb.CMSQueryRequest( + keyspace=keyspace, + name=name, + item=as_bytes(item, "item"), + ) + response = self._call(self._stub.CMSQuery, request, timeout) + return Present(int(response.count), bool(response.present)) diff --git a/clients/python/src/supercache/ops/counter.py b/clients/python/src/supercache/ops/counter.py new file mode 100644 index 0000000..10663c1 --- /dev/null +++ b/clients/python/src/supercache/ops/counter.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.types import Present + + +class CounterOps: + def incr(self, keyspace: str, name: str, delta: int, *, timeout: timedelta | None = None) -> int: + request = pb.IncrRequest(keyspace=keyspace, name=name, delta=delta) + response = self._call(self._stub.Incr, request, timeout) + return int(response.value) + + def counter_get(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> Present: + request = pb.CounterGetRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.CounterGet, request, timeout) + return Present(int(response.value), bool(response.present)) diff --git a/clients/python/src/supercache/ops/geo.py b/clients/python/src/supercache/ops/geo.py new file mode 100644 index 0000000..7cc660a --- /dev/null +++ b/clients/python/src/supercache/ops/geo.py @@ -0,0 +1,104 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.types import GeoMember +from supercache.wire import as_bytes + + +class GeoOps: + def geo_add( + self, + keyspace: str, + name: str, + member: bytes, + lon: float, + lat: float, + *, + timeout: timedelta | None = None, + ) -> None: + request = pb.GeoAddRequest( + keyspace=keyspace, + name=name, + member=as_bytes(member, "member"), + lon=lon, + lat=lat, + ) + self._call(self._stub.GeoAdd, request, timeout) + + def geo_rem(self, keyspace: str, name: str, member: bytes, *, timeout: timedelta | None = None) -> None: + request = pb.GeoRemRequest( + keyspace=keyspace, + name=name, + member=as_bytes(member, "member"), + ) + self._call(self._stub.GeoRem, request, timeout) + + def geo_pos( + self, + keyspace: str, + name: str, + member: bytes, + *, + timeout: timedelta | None = None, + ) -> tuple[float, float] | None: + request = pb.GeoPosRequest( + keyspace=keyspace, + name=name, + member=as_bytes(member, "member"), + ) + response = self._call(self._stub.GeoPos, request, timeout) + if not response.present: + return None + return float(response.lon), float(response.lat) + + def geo_card(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> int: + request = pb.GeoCardRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.GeoCard, request, timeout) + return int(response.card) + + def geo_dist( + self, + keyspace: str, + name: str, + a: bytes, + b: bytes, + *, + timeout: timedelta | None = None, + ) -> float | None: + request = pb.GeoDistRequest( + keyspace=keyspace, + name=name, + a=as_bytes(a, "a"), + b=as_bytes(b, "b"), + ) + response = self._call(self._stub.GeoDist, request, timeout) + if not response.present: + return None + return float(response.meters) + + def geo_radius( + self, + keyspace: str, + name: str, + lon: float, + lat: float, + radius_m: float, + limit: int, + *, + timeout: timedelta | None = None, + ) -> list[GeoMember]: + request = pb.GeoRadiusRequest( + keyspace=keyspace, + name=name, + lon=lon, + lat=lat, + radius_meters=radius_m, + limit=limit, + ) + response = self._call(self._stub.GeoRadius, request, timeout) + return [ + GeoMember(member.member, member.lon, member.lat, member.dist_meters) + for member in response.members + ] diff --git a/clients/python/src/supercache/ops/hash.py b/clients/python/src/supercache/ops/hash.py new file mode 100644 index 0000000..c0cb829 --- /dev/null +++ b/clients/python/src/supercache/ops/hash.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.types import HashField +from supercache.wire import as_bytes, as_field + + +class HashOps: + def hset( + self, + keyspace: str, + name: str, + field: str | bytes, + value: bytes, + *, + timeout: timedelta | None = None, + ) -> None: + request = pb.HSetRequest( + keyspace=keyspace, + name=name, + field=as_field(field), + value=as_bytes(value, "value"), + ) + self._call(self._stub.HSet, request, timeout) + + def hget(self, keyspace: str, name: str, field: str | bytes, *, timeout: timedelta | None = None) -> bytes | None: + request = pb.HGetRequest(keyspace=keyspace, name=name, field=as_field(field)) + response = self._call(self._stub.HGet, request, timeout) + if not response.present: + return None + return response.value + + def hdel(self, keyspace: str, name: str, field: str | bytes, *, timeout: timedelta | None = None) -> None: + request = pb.HDelRequest(keyspace=keyspace, name=name, field=as_field(field)) + self._call(self._stub.HDel, request, timeout) + + def hexists(self, keyspace: str, name: str, field: str | bytes, *, timeout: timedelta | None = None) -> bool: + request = pb.HExistsRequest(keyspace=keyspace, name=name, field=as_field(field)) + response = self._call(self._stub.HExists, request, timeout) + return bool(response.present) + + def hlen(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> int: + request = pb.HLenRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.HLen, request, timeout) + return int(response.len) + + def hgetall(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> list[HashField]: + request = pb.HGetAllRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.HGetAll, request, timeout) + return [HashField(field.field, field.value) for field in response.fields] diff --git a/clients/python/src/supercache/ops/hll.py b/clients/python/src/supercache/ops/hll.py new file mode 100644 index 0000000..e96d358 --- /dev/null +++ b/clients/python/src/supercache/ops/hll.py @@ -0,0 +1,22 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.types import Present +from supercache.wire import as_bytes + + +class HLLOps: + def hll_add(self, keyspace: str, name: str, item: bytes, *, timeout: timedelta | None = None) -> None: + request = pb.HLLAddRequest( + keyspace=keyspace, + name=name, + item=as_bytes(item, "item"), + ) + self._call(self._stub.HLLAdd, request, timeout) + + def hll_count(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> Present: + request = pb.HLLCountRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.HLLCount, request, timeout) + return Present(int(response.count), bool(response.present)) diff --git a/clients/python/src/supercache/ops/json.py b/clients/python/src/supercache/ops/json.py new file mode 100644 index 0000000..3c8e764 --- /dev/null +++ b/clients/python/src/supercache/ops/json.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.wire import as_bytes + + +class JsonOps: + def json_set( + self, + keyspace: str, + name: str, + path: str, + value: bytes, + *, + timeout: timedelta | None = None, + ) -> None: + request = pb.JsonSetRequest( + keyspace=keyspace, + name=name, + path=path, + value=as_bytes(value, "value"), + ) + self._call(self._stub.JsonSet, request, timeout) + + def json_get(self, keyspace: str, name: str, path: str, *, timeout: timedelta | None = None) -> bytes | None: + request = pb.JsonGetRequest(keyspace=keyspace, name=name, path=path) + response = self._call(self._stub.JsonGet, request, timeout) + if not response.present: + return None + return response.value + + def json_del(self, keyspace: str, name: str, path: str, *, timeout: timedelta | None = None) -> None: + request = pb.JsonDelRequest(keyspace=keyspace, name=name, path=path) + self._call(self._stub.JsonDel, request, timeout) diff --git a/clients/python/src/supercache/ops/list.py b/clients/python/src/supercache/ops/list.py new file mode 100644 index 0000000..3542604 --- /dev/null +++ b/clients/python/src/supercache/ops/list.py @@ -0,0 +1,63 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.wire import as_bytes + + +class ListOps: + def lpush(self, keyspace: str, name: str, item: bytes, *, timeout: timedelta | None = None) -> None: + request = pb.LPushRequest( + keyspace=keyspace, + name=name, + item=as_bytes(item, "item"), + ) + self._call(self._stub.LPush, request, timeout) + + def rpush(self, keyspace: str, name: str, item: bytes, *, timeout: timedelta | None = None) -> None: + request = pb.RPushRequest( + keyspace=keyspace, + name=name, + item=as_bytes(item, "item"), + ) + self._call(self._stub.RPush, request, timeout) + + def lpop(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> bytes | None: + request = pb.LPopRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.LPop, request, timeout) + if not response.present: + return None + return response.item + + def rpop(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> bytes | None: + request = pb.RPopRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.RPop, request, timeout) + if not response.present: + return None + return response.item + + def llen(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> int: + request = pb.LLenRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.LLen, request, timeout) + return int(response.len) + + def lindex(self, keyspace: str, name: str, index: int, *, timeout: timedelta | None = None) -> bytes | None: + request = pb.LIndexRequest(keyspace=keyspace, name=name, index=index) + response = self._call(self._stub.LIndex, request, timeout) + if not response.present: + return None + return response.item + + def lrange( + self, + keyspace: str, + name: str, + start: int, + stop: int, + *, + timeout: timedelta | None = None, + ) -> list[bytes]: + request = pb.LRangeRequest(keyspace=keyspace, name=name, start=start, stop=stop) + response = self._call(self._stub.LRange, request, timeout) + return list(response.items) diff --git a/clients/python/src/supercache/ops/set.py b/clients/python/src/supercache/ops/set.py new file mode 100644 index 0000000..8177754 --- /dev/null +++ b/clients/python/src/supercache/ops/set.py @@ -0,0 +1,43 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.wire import as_bytes + + +class SetOps: + def set_add(self, keyspace: str, name: str, item: bytes, *, timeout: timedelta | None = None) -> None: + request = pb.SetAddRequest( + keyspace=keyspace, + name=name, + item=as_bytes(item, "item"), + ) + self._call(self._stub.SetAdd, request, timeout) + + def set_remove(self, keyspace: str, name: str, item: bytes, *, timeout: timedelta | None = None) -> None: + request = pb.SetRemoveRequest( + keyspace=keyspace, + name=name, + item=as_bytes(item, "item"), + ) + self._call(self._stub.SetRemove, request, timeout) + + def set_contains(self, keyspace: str, name: str, item: bytes, *, timeout: timedelta | None = None) -> bool: + request = pb.SetContainsRequest( + keyspace=keyspace, + name=name, + item=as_bytes(item, "item"), + ) + response = self._call(self._stub.SetContains, request, timeout) + return bool(response.present) + + def set_card(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> int: + request = pb.SetCardRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.SetCard, request, timeout) + return int(response.card) + + def set_members(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> list[bytes]: + request = pb.SetMembersRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.SetMembers, request, timeout) + return list(response.members) diff --git a/clients/python/src/supercache/ops/stream.py b/clients/python/src/supercache/ops/stream.py new file mode 100644 index 0000000..56fb8c9 --- /dev/null +++ b/clients/python/src/supercache/ops/stream.py @@ -0,0 +1,59 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.types import Present, StreamEntry +from supercache.wire import as_bytes + + +class StreamOps: + def xadd(self, keyspace: str, name: str, payload: bytes, *, timeout: timedelta | None = None) -> str: + request = pb.XAddRequest( + keyspace=keyspace, + name=name, + payload=as_bytes(payload, "payload"), + ) + response = self._call(self._stub.XAdd, request, timeout) + return response.id + + def xrange( + self, + keyspace: str, + name: str, + start: str, + end: str, + count: int, + *, + timeout: timedelta | None = None, + ) -> list[StreamEntry]: + request = pb.XRangeRequest(keyspace=keyspace, name=name, start=start, end=end, count=count) + response = self._call(self._stub.XRange, request, timeout) + return [StreamEntry(entry.id, entry.payload) for entry in response.entries] + + def xrevrange( + self, + keyspace: str, + name: str, + start: str, + end: str, + count: int, + *, + timeout: timedelta | None = None, + ) -> list[StreamEntry]: + request = pb.XRevRangeRequest(keyspace=keyspace, name=name, start=start, end=end, count=count) + response = self._call(self._stub.XRevRange, request, timeout) + return [StreamEntry(entry.id, entry.payload) for entry in response.entries] + + def xlen(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> Present: + request = pb.XLenRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.XLen, request, timeout) + return Present(int(response.n), bool(response.present)) + + def xdel(self, keyspace: str, name: str, id: str, *, timeout: timedelta | None = None) -> None: + request = pb.XDelRequest(keyspace=keyspace, name=name, id=id) + self._call(self._stub.XDel, request, timeout) + + def xtrim(self, keyspace: str, name: str, max_len: int, *, timeout: timedelta | None = None) -> None: + request = pb.XTrimRequest(keyspace=keyspace, name=name, max_len=max_len) + self._call(self._stub.XTrim, request, timeout) diff --git a/clients/python/src/supercache/ops/topk.py b/clients/python/src/supercache/ops/topk.py new file mode 100644 index 0000000..32b390a --- /dev/null +++ b/clients/python/src/supercache/ops/topk.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.types import TopKEntry, TopKResult +from supercache.wire import as_bytes + + +class TopKOps: + def topk_add(self, keyspace: str, name: str, item: bytes, *, timeout: timedelta | None = None) -> None: + request = pb.TopKAddRequest( + keyspace=keyspace, + name=name, + item=as_bytes(item, "item"), + ) + self._call(self._stub.TopKAdd, request, timeout) + + def topk_list(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> TopKResult: + request = pb.TopKListRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.TopKList, request, timeout) + entries = [TopKEntry(entry.item, int(entry.count)) for entry in response.entries] + return TopKResult(entries, bool(response.present)) diff --git a/clients/python/src/supercache/ops/vecset.py b/clients/python/src/supercache/ops/vecset.py new file mode 100644 index 0000000..fce7720 --- /dev/null +++ b/clients/python/src/supercache/ops/vecset.py @@ -0,0 +1,81 @@ +from __future__ import annotations + +from datetime import timedelta +from typing import Sequence + +from supercache._gen import cache_pb2 as pb +from supercache.types import Present, VSimHit +from supercache.wire import as_bytes, as_vector + + +class VecSetOps: + def vadd( + self, + keyspace: str, + name: str, + member: bytes, + vec: Sequence[float], + *, + timeout: timedelta | None = None, + ) -> None: + request = pb.VAddRequest( + keyspace=keyspace, + name=name, + member=as_bytes(member, "member"), + vec=as_vector(vec), + ) + self._call(self._stub.VAdd, request, timeout) + + def vrem(self, keyspace: str, name: str, member: bytes, *, timeout: timedelta | None = None) -> None: + request = pb.VRemRequest( + keyspace=keyspace, + name=name, + member=as_bytes(member, "member"), + ) + self._call(self._stub.VRem, request, timeout) + + def vsim( + self, + keyspace: str, + name: str, + vec: Sequence[float], + k: int, + *, + timeout: timedelta | None = None, + ) -> list[VSimHit]: + request = pb.VSimRequest( + keyspace=keyspace, + name=name, + vec=as_vector(vec), + k=k, + ) + response = self._call(self._stub.VSim, request, timeout) + return [VSimHit(hit.member, hit.score) for hit in response.hits] + + def vcard(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> Present: + request = pb.VCardRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.VCard, request, timeout) + return Present(int(response.n), bool(response.present)) + + def vdim(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> Present: + request = pb.VDimRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.VDim, request, timeout) + return Present(int(response.dim), bool(response.present)) + + def vemb( + self, + keyspace: str, + name: str, + member: bytes, + *, + timeout: timedelta | None = None, + ) -> list[float] | None: + request = pb.VEmbRequest( + keyspace=keyspace, + name=name, + member=as_bytes(member, "member"), + ) + response = self._call(self._stub.VEmb, request, timeout) + if not response.found: + return None + return [float(x) for x in response.vec] diff --git a/clients/python/src/supercache/ops/zset.py b/clients/python/src/supercache/ops/zset.py new file mode 100644 index 0000000..b3d43d8 --- /dev/null +++ b/clients/python/src/supercache/ops/zset.py @@ -0,0 +1,81 @@ +from __future__ import annotations + +from datetime import timedelta + +from supercache._gen import cache_pb2 as pb +from supercache.types import ZMember +from supercache.wire import as_bytes + + +class ZSetOps: + def zadd( + self, + keyspace: str, + name: str, + member: bytes, + score: float, + *, + timeout: timedelta | None = None, + ) -> None: + request = pb.ZAddRequest( + keyspace=keyspace, + name=name, + member=as_bytes(member, "member"), + score=score, + ) + self._call(self._stub.ZAdd, request, timeout) + + def zrem(self, keyspace: str, name: str, member: bytes, *, timeout: timedelta | None = None) -> None: + request = pb.ZRemRequest( + keyspace=keyspace, + name=name, + member=as_bytes(member, "member"), + ) + self._call(self._stub.ZRem, request, timeout) + + def zscore(self, keyspace: str, name: str, member: bytes, *, timeout: timedelta | None = None) -> float | None: + request = pb.ZScoreRequest( + keyspace=keyspace, + name=name, + member=as_bytes(member, "member"), + ) + response = self._call(self._stub.ZScore, request, timeout) + if not response.present: + return None + return float(response.score) + + def zcard(self, keyspace: str, name: str, *, timeout: timedelta | None = None) -> int: + request = pb.ZCardRequest(keyspace=keyspace, name=name) + response = self._call(self._stub.ZCard, request, timeout) + return int(response.card) + + def zrange( + self, + keyspace: str, + name: str, + start: int, + stop: int, + *, + timeout: timedelta | None = None, + ) -> list[ZMember]: + request = pb.ZRangeRequest(keyspace=keyspace, name=name, start=start, stop=stop) + response = self._call(self._stub.ZRange, request, timeout) + return [ZMember(member.member, member.score) for member in response.members] + + def zrange_by_score( + self, + keyspace: str, + name: str, + min_score: float, + max_score: float, + *, + timeout: timedelta | None = None, + ) -> list[ZMember]: + request = pb.ZRangeByScoreRequest( + keyspace=keyspace, + name=name, + min=min_score, + max=max_score, + ) + response = self._call(self._stub.ZRangeByScore, request, timeout) + return [ZMember(member.member, member.score) for member in response.members] diff --git a/clients/python/src/supercache/session.py b/clients/python/src/supercache/session.py new file mode 100644 index 0000000..b46e786 --- /dev/null +++ b/clients/python/src/supercache/session.py @@ -0,0 +1,131 @@ +"""Sticky multi-seed dialing, same policy as cmd/sc.""" + +from __future__ import annotations + +from datetime import timedelta +from threading import Lock +from typing import Callable, TypeVar + +from supercache.client import Client, dial, dial_tls +from supercache.errors import StatusError, is_transport +from supercache.types import TLS + +T = TypeVar("T") + + +class Session: + """Walk seeds on dial. Retry a call once after UNAVAILABLE or a reset connection. + + A call-level deadline is not retried: the server may already have applied it. + """ + + def __init__( + self, + addrs: list[str], + *, + tls: TLS | None = None, + timeout: timedelta | None = None, + probe_s: float = 0.5, + ) -> None: + if not addrs: + raise ValueError("at least one address is required") + self._addrs = list(addrs) + self._tls = tls + self._timeout = timeout + self._probe = probe_s + self._idx = 0 + self._client: Client | None = None + self._addr: str | None = None + self._lock = Lock() + + def __enter__(self) -> Session: + return self + + def __exit__(self, *exc: object) -> None: + self.close() + + @property + def connected_addr(self) -> str | None: + return self._addr + + def close(self) -> None: + with self._lock: + if self._client is not None: + self._client.close() + self._client = None + self._addr = None + + def call(self, fn: Callable[[Client], T]) -> T: + return self._with_client(fn) + + def __getattr__(self, name: str): + if name.startswith("_"): + raise AttributeError(name) + attr = getattr(Client, name, None) + if attr is None or not callable(attr): + raise AttributeError(name) + + def wrapper(*args, **kwargs): + return self._with_client(lambda c: getattr(c, name)(*args, **kwargs)) + + return wrapper + + def _dial(self, addr: str) -> Client: + if self._tls is None: + return dial(addr, timeout=self._timeout) + tls = self._tls + return dial_tls( + addr, + tls.ca_file, + tls.server_name, + tls.client_cert, + tls.client_key, + timeout=self._timeout, + ) + + def _ensure(self) -> Client: + with self._lock: + if self._client is not None: + return self._client + errors: list[str] = [] + n = len(self._addrs) + for i in range(n): + idx = (self._idx + i) % n + addr = self._addrs[idx] + cli: Client | None = None + try: + cli = self._dial(addr) + cli.wait_ready(self._probe) + except Exception as exc: # noqa: BLE001 — dial failure walks the list + errors.append(f"{addr}: {exc}") + if cli is not None: + cli.close() + continue + self._client = cli + self._idx = idx + self._addr = addr + return cli + raise StatusError("UNAVAILABLE", "all cache seeds failed:\n " + "\n ".join(errors)) + + def _invalidate(self) -> None: + with self._lock: + if self._client is not None: + self._client.close() + self._client = None + self._idx = (self._idx + 1) % len(self._addrs) + self._addr = None + + def _with_client(self, fn: Callable[[Client], T]) -> T: + cli = self._ensure() + try: + return fn(cli) + except StatusError as err: + if not is_transport(err): + raise + first = err + self._invalidate() + try: + cli = self._ensure() + except Exception as err2: # noqa: BLE001 + raise StatusError("UNAVAILABLE", f"{first} (re-dial: {err2})") from err2 + return fn(cli) diff --git a/clients/python/src/supercache/types.py b/clients/python/src/supercache/types.py new file mode 100644 index 0000000..c8aa48b --- /dev/null +++ b/clients/python/src/supercache/types.py @@ -0,0 +1,77 @@ +"""Values returned by Client. These are not wire messages.""" + +from __future__ import annotations + +from dataclasses import dataclass + + +@dataclass(frozen=True) +class ZMember: + member: bytes + score: float + + +@dataclass(frozen=True) +class GeoMember: + member: bytes + lon: float + lat: float + dist: float + + +@dataclass(frozen=True) +class HashField: + field: bytes + value: bytes + + +@dataclass(frozen=True) +class StreamEntry: + id: str + payload: bytes + + +@dataclass(frozen=True) +class VSimHit: + member: bytes + score: float + + +@dataclass(frozen=True) +class TopKEntry: + item: bytes + count: int + + +@dataclass(frozen=True) +class Present: + """A read that distinguishes a missing structure from a real zero.""" + + value: int + found: bool + + +@dataclass(frozen=True) +class TopKResult: + entries: list[TopKEntry] + found: bool + + +@dataclass(frozen=True) +class BitValue: + value: bool + found: bool + + +@dataclass(frozen=True) +class BitPos: + pos: int + found: bool + + +@dataclass(frozen=True) +class TLS: + ca_file: str + server_name: str + client_cert: str | None = None + client_key: str | None = None diff --git a/clients/python/src/supercache/wire.py b/clients/python/src/supercache/wire.py new file mode 100644 index 0000000..baeb5da --- /dev/null +++ b/clients/python/src/supercache/wire.py @@ -0,0 +1,50 @@ +"""Caller values to proto fields. Not part of the public client.""" + +from __future__ import annotations + +from datetime import timedelta +from typing import Sequence + +from supercache.errors import KeyErrorItem, KeyErrors, PeerFailure, PeerFailures + + +def as_bytes(value: bytes, what: str) -> bytes: + if isinstance(value, (bytes, bytearray, memoryview)): + return bytes(value) + raise TypeError(f"{what} must be bytes") + + +def as_field(value: str | bytes) -> bytes: + if isinstance(value, str): + return value.encode("utf-8") + return as_bytes(value, "field") + + +def as_vector(vec: Sequence[float]) -> list[float]: + if isinstance(vec, (str, bytes, bytearray)): + raise TypeError("vector must be a sequence of floats") + return [float(x) for x in vec] + + +def ttl_fields(ttl: timedelta | None) -> tuple[int, bool]: + """(ttl_nanos, ttl_set). None leaves the flag false. Zero sets the flag.""" + if ttl is None: + return 0, False + nanos = int(ttl.total_seconds() * 1_000_000_000) + return nanos, True + + +def raise_key_errors(errors) -> None: + if not errors: + return + items = [] + for err in errors: + peers = [PeerFailure(p.peer_id, p.message) for p in err.peer_failures] + items.append(KeyErrorItem(err.key, err.message, peers)) + raise KeyErrors(items) + + +def raise_peer_failures(failures) -> None: + if not failures: + return + raise PeerFailures([PeerFailure(p.peer_id, p.message) for p in failures]) diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py new file mode 100644 index 0000000..5d17fbe --- /dev/null +++ b/clients/python/tests/test_client.py @@ -0,0 +1,336 @@ +"""Client behavior against clients/conformance and a tiny local gRPC stub.""" + +from __future__ import annotations + +import signal +import subprocess +import uuid +from concurrent import futures +from datetime import timedelta +from pathlib import Path + +import grpc +import pytest + +from supercache import ( + KeyErrors, + NotFound, + Session, + StatusError, + TLS, + dial, + dial_tls, +) +from supercache._gen import cache_pb2 as pb +from supercache._gen import cache_pb2_grpc as pb_grpc + + +def repo_root() -> Path: + here = Path(__file__).resolve() + for p in here.parents: + if (p / "go.mod").exists(): + return p + raise RuntimeError("go.mod not found") + + +class Proc: + def __init__(self, proc: subprocess.Popen, meta: dict[str, str]) -> None: + self.proc = proc + self.meta = meta + + @property + def addr(self) -> str: + return self.meta["addr"] + + def stop(self) -> None: + if self.proc.poll() is None: + self.proc.send_signal(signal.SIGTERM) + self.proc.wait(timeout=15) + + +def _start(binary: Path, *args: str) -> Proc: + proc = subprocess.Popen( + [str(binary), *args], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + assert proc.stdout is not None + meta: dict[str, str] = {} + need = "client_key" if ("-tls" in args or "-mtls" in args) else "addr" + while need not in meta: + line = proc.stdout.readline() + if not line: + err = proc.stderr.read() if proc.stderr else "" + raise RuntimeError(f"conformance exited before {need}: {err}") + line = line.strip() + if "=" not in line: + continue + k, v = line.split("=", 1) + meta[k] = v + return Proc(proc, meta) + + +@pytest.fixture(scope="module") +def servers(): + root = repo_root() + binary = root / "clients" / "python" / ".venv" / "conformance" + # The venv directory is gitignored. The binary is a test artifact next to it. + binary.parent.mkdir(parents=True, exist_ok=True) + subprocess.check_call(["go", "build", "-o", str(binary), "./clients/conformance"], cwd=root) + plain = _start(binary) + tls = _start(binary, "-tls") + mtls = _start(binary, "-mtls") + yield {"plain": plain, "tls": tls, "mtls": mtls} + for proc in (plain, tls, mtls): + proc.stop() + + +@pytest.fixture(scope="module") +def client(servers): + c = dial(servers["plain"].addr) + yield c + c.close() + + +def nid() -> str: + return uuid.uuid4().hex[:12] + + +def test_get_put_delete_and_not_found(client): + key = "k-" + nid() + with pytest.raises(NotFound) as missed: + client.get("cacheonly", key) + assert not isinstance(missed.value, StatusError) + client.put("cacheonly", key, b"v") + assert client.get("cacheonly", key) == b"v" + client.delete("cacheonly", key) + with pytest.raises(NotFound): + client.get("cacheonly", key) + + +def test_ttl_omitted_and_zero(client): + a, b = "ttl-a-" + nid(), "ttl-b-" + nid() + client.put("cacheonly", a, b"a") + client.put("cacheonly", b, b"b", ttl=timedelta(0)) + assert client.get("cacheonly", a) == b"a" + assert client.get("cacheonly", b) == b"b" + + +def test_put_many_and_empty_key(client): + a, b = "m-" + nid(), "n-" + nid() + client.put_many("cacheonly", [(a, b"1"), (b, b"2")]) + assert client.get("cacheonly", a) == b"1" + client.delete_many("cacheonly", [a, b]) + with pytest.raises(NotFound): + client.get("cacheonly", a) + with pytest.raises(KeyErrors) as exc: + client.put_many("cacheonly", [("", b"x"), ("", b"y")]) + assert exc.value.errors + assert all(item.key == "" for item in exc.value.errors) + + +def test_missing_keyspace_is_status_not_found_class(client): + with pytest.raises(StatusError) as exc: + client.get("nope", "k") + assert exc.value.code == "NOT_FOUND" + assert not isinstance(exc.value, NotFound) + with pytest.raises(StatusError) as put_exc: + client.put("nope", "k", b"v") + assert put_exc.value.code == "NOT_FOUND" + + +def test_loadthrough_and_wrong_mode(client): + assert client.get("loadthrough", "seeded") == b"from-source" + with pytest.raises(NotFound): + client.get("loadthrough", "missing") + with pytest.raises(StatusError) as exc: + client.get("set", "anything") + assert exc.value.code == "INVALID_ARGUMENT" + + +def test_structures(client): + name = nid() + assert client.bloom_test("bloom", name, b"ghost") is False + client.bloom_add("bloom", name, b"alice") + assert client.bloom_test("bloom", name, b"alice") is True + + client.set_add("set", name, b"x") + assert client.set_contains("set", name, b"x") is True + assert client.set_card("set", name) == 1 + assert b"x" in client.set_members("set", name) + client.set_remove("set", name, b"x") + assert client.set_contains("set", name, b"x") is False + + client.zadd("zset", name, b"alice", 10) + client.zadd("zset", name, b"bob", 20) + assert client.zscore("zset", name, b"alice") == 10 + assert client.zcard("zset", name) == 2 + assert [m.member for m in client.zrange("zset", name, 0, -1)] == [b"alice", b"bob"] + assert [m.member for m in client.zrange_by_score("zset", name, 10, 10)] == [b"alice"] + client.zrem("zset", name, b"bob") + assert client.zscore("zset", name, b"bob") is None + + client.geo_add("geo", name, b"a", -74.0, 40.7) + client.geo_add("geo", name, b"b", -74.1, 40.8) + assert client.geo_pos("geo", name, b"a") == (-74.0, 40.7) + dist = client.geo_dist("geo", name, b"a", b"b") + assert dist is not None and dist > 0 + assert client.geo_card("geo", name) == 2 + hits = client.geo_radius("geo", name, -74.0, 40.7, 50_000, 10) + assert any(h.member == b"a" for h in hits) + client.geo_rem("geo", name, b"b") + assert client.geo_pos("geo", name, b"b") is None + + client.lpush("list", name, b"b") + client.lpush("list", name, b"a") + client.rpush("list", name, b"c") + assert client.llen("list", name) == 3 + assert client.lindex("list", name, 0) == b"a" + assert client.lrange("list", name, 0, -1) == [b"a", b"b", b"c"] + assert client.lpop("list", name) == b"a" + assert client.rpop("list", name) == b"c" + + client.hset("hash", name, "email", b"a@b") + assert client.hget("hash", name, "email") == b"a@b" + assert client.hexists("hash", name, "email") is True + assert client.hlen("hash", name) == 1 + assert client.hgetall("hash", name)[0].field == b"email" + client.hdel("hash", name, "email") + assert client.hget("hash", name, "email") is None + + assert client.incr("counter", name, 2) == 2 + assert client.incr("counter", name, 3) == 5 + got = client.counter_get("counter", name) + assert got.found and got.value == 5 + + client.json_set("json", name, "$.name", b'"Ada"') + assert client.json_get("json", name, "$.name") == b'"Ada"' + client.json_del("json", name, "$.name") + assert client.json_get("json", name, "$.name") is None + + client.bit_set("bitmap", name, 0, True) + bit = client.bit_get("bitmap", name, 0) + assert bit.found and bit.value is True + assert client.bit_count("bitmap", name, 0, -1) >= 1 + pos = client.bit_pos("bitmap", name, True, 0, -1) + assert pos.found and pos.pos == 0 + + client.hll_add("hll", name, b"alice") + hll = client.hll_count("hll", name) + assert hll.found and hll.value >= 1 + + client.topk_add("topk", name, b"t001") + client.topk_add("topk", name, b"t001") + top = client.topk_list("topk", name) + assert top.found and any(e.item == b"t001" for e in top.entries) + + client.cms_incr("cms", name, b"t003", 4) + cms = client.cms_query("cms", name, b"t003") + assert cms.found and cms.value >= 4 + + client.vadd("vectorset", name, b"east", [1, 0, 0, 0]) + dim = client.vdim("vectorset", name) + assert dim.found and dim.value == 4 + card = client.vcard("vectorset", name) + assert card.found and card.value == 1 + emb = client.vemb("vectorset", name, b"east") + assert emb is not None and len(emb) == 4 + sim = client.vsim("vectorset", name, [1, 0, 0, 0], 1) + assert sim and sim[0].member == b"east" + client.vrem("vectorset", name, b"east") + + sid = client.xadd("stream", name, b"hello") + assert sid + length = client.xlen("stream", name) + assert length.found and length.value >= 1 + rows = client.xrange("stream", name, "-", "+", 10) + assert rows and rows[0].payload == b"hello" + rev = client.xrevrange("stream", name, "-", "+", 10) + assert rev and rev[0].id == sid + client.xdel("stream", name, sid) + client.xtrim("stream", name, 1) + + +def test_tls_and_mtls(servers): + tls = servers["tls"] + key = "tls-" + nid() + c = dial_tls(tls.addr, tls.meta["ca"], "localhost") + try: + c.put("cacheonly", key, b"secret") + assert c.get("cacheonly", key) == b"secret" + finally: + c.close() + + with pytest.raises(ValueError): + dial_tls(tls.addr, tls.meta["ca"], "") + + mtls = servers["mtls"] + secure = dial_tls( + mtls.addr, + mtls.meta["ca"], + "localhost", + mtls.meta["client_cert"], + mtls.meta["client_key"], + ) + try: + key = "mtls-" + nid() + secure.put("cacheonly", key, b"m") + assert secure.get("cacheonly", key) == b"m" + finally: + secure.close() + + bare = dial_tls(mtls.addr, mtls.meta["ca"], "localhost") + try: + with pytest.raises(StatusError): + bare.put("cacheonly", "nope", b"x") + finally: + bare.close() + + +def test_session_skips_closed_port(servers): + live = servers["plain"].addr + s = Session(["127.0.0.1:1", live], timeout=timedelta(seconds=2)) + try: + with pytest.raises(NotFound): + s.get("cacheonly", "missing-" + nid()) + assert s.connected_addr == live + finally: + s.close() + + +def test_session_retries_unavailable_once_and_not_notfound(): + class Once(pb_grpc.CacheServicer): + def __init__(self) -> None: + self.gets = 0 + + def Get(self, request, context): + self.gets += 1 + if request.key == "flaky" and self.gets == 1: + context.abort(grpc.StatusCode.UNAVAILABLE, "down") + if request.key == "miss": + return pb.GetResponse(found=False) + return pb.GetResponse(found=True, value=b"ok") + + svc = Once() + server = grpc.server(futures.ThreadPoolExecutor(max_workers=2)) + pb_grpc.add_CacheServicer_to_server(svc, server) + port = server.add_insecure_port("127.0.0.1:0") + server.start() + s = Session([f"127.0.0.1:{port}"]) + try: + assert s.get("cacheonly", "flaky") == b"ok" + assert svc.gets == 2 + before = svc.gets + with pytest.raises(NotFound): + s.get("cacheonly", "miss") + assert svc.gets == before + 1 + finally: + s.close() + server.stop(0) + + +def test_close_is_idempotent(servers): + c = dial(servers["plain"].addr) + c.close() + c.close() diff --git a/docs/API.md b/docs/API.md index cdbb59b..f0dfba1 100644 --- a/docs/API.md +++ b/docs/API.md @@ -25,9 +25,15 @@ go run ./cmd/supercache-node \ ### Clients - **Go:** `pkg/client` +- **Python:** `clients/python` (`import supercache`, sync). Install from source; not published. +- **Node.js:** `clients/node` (`@code0987/supercache`, Promises, Node 22+). Install from source; the package is `private`. - **CLI:** `cmd/sc` (`sc get` / `put` / `del`, `bloom`, `sadd`…, `zadd`…, `geoadd`…, `lpush`…, `hset`…, `incr` / `cget`, `jsonset`…, `bitset`…, `vadd`…, `xadd`…, or REPL) - **Protos:** `api/proto/cache.proto`, `api/proto/peer.proto` (peer is mesh-internal) +Python and Node speak the Cache port only. They follow `pkg/client`: a Get with `found=false` raises `NotFound`. A gRPC status is a different error, including `NOT_FOUND` when the keyspace is missing (`supercache: keyspace not found`). `PutMany` / `DeleteMany` per-key failures and `Delete` peer failures are raised from the response body, not from the status. Omitted TTL leaves `ttl_set` false. An explicit zero TTL sets `ttl_set` and stores no expiry. + +`scripts/check-client-surface.py` fails CI unless every Cache RPC below is wrapped by both clients and named in this file: Get, Put, PutMany, Delete, DeleteMany, BloomAdd, BloomTest, SetAdd, SetRemove, SetContains, SetCard, SetMembers, ZAdd, ZRem, ZScore, ZCard, ZRange, ZRangeByScore, GeoAdd, GeoRem, GeoPos, GeoCard, GeoDist, GeoRadius, LPush, RPush, LPop, RPop, LLen, LIndex, LRange, HSet, HGet, HDel, HExists, HLen, HGetAll, Incr, CounterGet, JsonSet, JsonGet, JsonDel, BitSet, BitGet, BitCount, BitPos, HLLAdd, HLLCount, TopKAdd, TopKList, CMSIncr, CMSQuery, VAdd, VRem, VSim, VCard, VDim, VEmb, XAdd, XRange, XRevRange, XLen, XDel, XTrim. + ## Keyspace modes Each keyspace has exactly one mode. Verbs that do not match the mode return invalid argument. diff --git a/docs/design/2026-10-08-polyglot-clients.md b/docs/design/2026-10-08-polyglot-clients.md new file mode 100644 index 0000000..bb56a28 --- /dev/null +++ b/docs/design/2026-10-08-polyglot-clients.md @@ -0,0 +1,67 @@ +# Python and Node.js Cache clients + +**Status:** approved +**Branch:** feat/polyglot-clients + +## Problem + +Applications outside Go can only speak SuperCache by hand-rolling gRPC against `api/proto/cache.proto`. `pkg/client` hides the awkward parts: `GetResponse.found=false` is `ErrNotFound`, batch and delete failures come back in the body (not as a status), and `ttl_set` is distinct from a zero TTL. `cmd/sc` adds sticky multi-seed dialing on top. There is no Python or Node package that does this, and nothing fails CI when `cache.proto` changes and those callers drift. + +## Non-goals + +- No HTTP/JSON gateway, no Peer-mesh client, no Redis protocol, no in-process engine, no browser / gRPC-Web client. +- No PyPI or npm publish. Packages are in-repo and `private` on the Node side. +- No change to Get, Put, Delete, replication, hints, tombstones, or membership. +- No asyncio client, admin HTTP SDK, or further languages in this change. + +## Contract + +- Public surface: `clients/python` (`supercache`, sync, Python 3.11+) and `clients/node` (`@code0987/supercache`, async Promises, Node 22+). Both dial the Cache port only. +- Generated stubs are checked in under `clients/python/src/supercache/_gen` and `clients/node/src/gen`. Hand-written facades are what READMEs document. `scripts/gen-clients.sh` regenerates stubs from `cache.proto` only (protoc 28.3, `grpcio-tools` 1.69.0, `ts-proto` 2.7.7). It does not touch `api/gen`. +- Method names mirror `pkg/client`. Python uses snake_case and Redis-style one-word commands (`zadd`, `lpush`, `hget`, `xrevrange`, `zrange_by_score`). Node uses camelCase (`putMany`, `zRangeByScore`, `topKList`, `xRevRange`). +- Keys, keyspaces, JSON paths, and stream ids are strings. Values, items, members, and payloads are bytes (`bytes` in Python, `Uint8Array` in Node). Node also accepts a string and UTF-8-encodes it. Hash fields accept string or bytes. +- `ttl` omitted → `ttl_set=false`. Explicit zero → `ttl_set=true` and `ttl_nanos=0`. Python takes `datetime.timedelta | None`. Node takes `ttlMs?: number`. +- `get` miss raises `NotFound`. That type is only `found=false`. A gRPC status, including `NOT_FOUND` for a missing keyspace, is `StatusError` with `code` and `message`. +- `PutMany` / `DeleteMany` body errors raise `KeyErrors`. `Delete` body peer failures raise `PeerFailures`. Those RPCs are successes on the wire. +- Bool reads (`bloom_test`, `set_contains`, `hexists`) return false for a miss. Byte reads (`hget`, `lpop`, `lindex`, `json_get`, `vemb`) return null. `bit_get` returns `{value, found}`. Counts that can be absent (`counter_get`, `hll_count`, `cms_query`, `vcard`, `vdim`, `xlen`) return `{value, found}`. `topk_list` returns `{entries, found}`. Missing structures return empty or 0, matching Go. +- `Session` copies `cmd/sc` sticky seeds: walk the list once on dial, and on gRPC `UNAVAILABLE` or a connection reset/refused/broken-pipe, drop the client, advance one seed, and retry the call once. Do not retry `NotFound`, `INVALID_ARGUMENT`, `KeyErrors`, `PeerFailures`, or a call-level deadline (an `Incr` may already have been applied). Library default is no per-call deadline. `Session` accepts an optional timeout applied to each attempt. +- Plaintext `dial` for local use. `dial_tls(addr, ca_file, server_name, client_cert=None, client_key=None)` for TLS. `server_name` is required. Client cert and key are both set or both omitted. +- CI job `clients-up-to-date` regenerates stubs and fails on `git diff`, then `scripts/check-client-surface.py` fails unless every `service Cache` RPC has a Python method, a Node method, and its RPC name in `docs/API.md`. + +Who stores a copy, RF, hints, and TTL behavior are unchanged. An existing Go client can still assume the current server contract. + +## Approach + +`clients/conformance` is a single-node Engine plus Cache gRPC server. `go run ./clients/conformance` prints `addr=` and blocks. `-tls` / `-mtls` also print PEM paths. It registers one keyspace per mode, including LoadThrough backed by `datasource.Map{"seeded": "from-source"}`. Language tests build that binary and talk to it. + +Facades are thin wrappers over the generated Cache stub. They do not pre-check keyspace mode. Wrong-mode verbs stay server `INVALID_ARGUMENT`. + +Rejected alternatives: + +- REST gateway: second public protocol, and the cache port is gRPC today. +- Separate client repos: stubs drift from `cache.proto`. +- KV-only first cut: a stale subset of one service. +- Connect-RPC: the server is `google.golang.org/grpc`. + +## Tests (write these first, after approval) + +| Test | Package | Asserts | +|------|---------|---------| +| Boot, keyspace list, load-through seed, TLS PEM files | `clients/conformance` | One keyspace per mode; `seeded` loads; certs parse; plaintext gRPC Put/Get works | +| Get/Put/Delete, PutMany empty key, missing keyspace, ttl 0 vs omitted, every mode happy path, wrong-mode Get, TLS and mTLS, session failover | `clients/python/tests` | `NotFound` is not status `NOT_FOUND`; `KeyErrors` on empty key; one round-trip per mode; closed port then live seed; `UNAVAILABLE` retried once; `NotFound` not retried | +| Same behavior table | `clients/node/test` | Same assertions on the Promise client | +| Surface check | `scripts/check-client-surface.py` | Every Cache RPC maps to both facades and appears in `docs/API.md` | + +## Bench risk + +No shared smoke or micro cell should move. Hot path (Get-hit, Put, store mutex): no. This change does not edit `pkg/engine` or `pkg/store`. CI `bench` still runs and must stay inside ±10% with flat Get-hit allocs. + +## PR Plan + +The work lands as one branch sequence. Do not merge until the bench comment is inside the gate and the user says merge. + +1. **Conformance and freshness gate** — `clients/conformance`, `scripts/gen-clients.sh`, `scripts/check-client-surface.py`, `.github/workflows/ci.yml` job `clients-up-to-date`, this design. Depends on nothing. +2. **Python client** — `clients/python`, Python half of job `clients`, README / API.md / PLAN. Depends on PR 1. +3. **Node client** — `clients/node`, Node half of job `clients`, the same docs for Node. Depends on PR 1. Parallel with PR 2 after the generator exists. + +Publishing to PyPI and npm is a later design. diff --git a/docs/design/README.md b/docs/design/README.md index 4447237..792fcea 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -34,6 +34,7 @@ Do not implement from a draft. | [2026-09-02-refactor-geo.md](./2026-09-02-refactor-geo.md) | ModeGeo file layout (no contract) | | [2026-09-02-feature-folders.md](./2026-09-02-feature-folders.md) | Feature folders (List first) | | [2026-09-04-mode-vector-set.md](./2026-09-04-mode-vector-set.md) | `ModeVectorSet` | +| [2026-10-08-polyglot-clients.md](./2026-10-08-polyglot-clients.md) | Python and Node Cache clients | | [2026-09-08-mode-stream.md](./2026-09-08-mode-stream.md) | `ModeStream` | | [2026-09-08-lab-mode-stream.md](./2026-09-08-lab-mode-stream.md) | Lab Stream chapter | | [2026-08-25-list-counter-version.md](./2026-08-25-list-counter-version.md) | List/Counter snapshot version | diff --git a/scripts/check-client-surface.py b/scripts/check-client-surface.py new file mode 100644 index 0000000..263d717 --- /dev/null +++ b/scripts/check-client-surface.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 +"""Fail unless every Cache RPC has a Python method, a Node method, and an API.md mention. + +The table is the facade contract from docs/design/2026-10-08-polyglot-clients.md. +A new rpc in api/proto/cache.proto fails until this table, both clients, and +docs/API.md all grow the method. +""" + +from __future__ import annotations + +import re +import sys +from pathlib import Path + +# (rpc, python method, node method) +SURFACE = [ + ("Get", "get", "get"), + ("Put", "put", "put"), + ("PutMany", "put_many", "putMany"), + ("Delete", "delete", "delete"), + ("DeleteMany", "delete_many", "deleteMany"), + ("BloomAdd", "bloom_add", "bloomAdd"), + ("BloomTest", "bloom_test", "bloomTest"), + ("SetAdd", "set_add", "setAdd"), + ("SetRemove", "set_remove", "setRemove"), + ("SetContains", "set_contains", "setContains"), + ("SetCard", "set_card", "setCard"), + ("SetMembers", "set_members", "setMembers"), + ("ZAdd", "zadd", "zAdd"), + ("ZRem", "zrem", "zRem"), + ("ZScore", "zscore", "zScore"), + ("ZCard", "zcard", "zCard"), + ("ZRange", "zrange", "zRange"), + ("ZRangeByScore", "zrange_by_score", "zRangeByScore"), + ("GeoAdd", "geo_add", "geoAdd"), + ("GeoRem", "geo_rem", "geoRem"), + ("GeoPos", "geo_pos", "geoPos"), + ("GeoCard", "geo_card", "geoCard"), + ("GeoDist", "geo_dist", "geoDist"), + ("GeoRadius", "geo_radius", "geoRadius"), + ("LPush", "lpush", "lPush"), + ("RPush", "rpush", "rPush"), + ("LPop", "lpop", "lPop"), + ("RPop", "rpop", "rPop"), + ("LLen", "llen", "lLen"), + ("LIndex", "lindex", "lIndex"), + ("LRange", "lrange", "lRange"), + ("HSet", "hset", "hSet"), + ("HGet", "hget", "hGet"), + ("HDel", "hdel", "hDel"), + ("HExists", "hexists", "hExists"), + ("HLen", "hlen", "hLen"), + ("HGetAll", "hgetall", "hGetAll"), + ("Incr", "incr", "incr"), + ("CounterGet", "counter_get", "counterGet"), + ("JsonSet", "json_set", "jsonSet"), + ("JsonGet", "json_get", "jsonGet"), + ("JsonDel", "json_del", "jsonDel"), + ("BitSet", "bit_set", "bitSet"), + ("BitGet", "bit_get", "bitGet"), + ("BitCount", "bit_count", "bitCount"), + ("BitPos", "bit_pos", "bitPos"), + ("HLLAdd", "hll_add", "hllAdd"), + ("HLLCount", "hll_count", "hllCount"), + ("TopKAdd", "topk_add", "topKAdd"), + ("TopKList", "topk_list", "topKList"), + ("CMSIncr", "cms_incr", "cmsIncr"), + ("CMSQuery", "cms_query", "cmsQuery"), + ("VAdd", "vadd", "vAdd"), + ("VRem", "vrem", "vRem"), + ("VSim", "vsim", "vSim"), + ("VCard", "vcard", "vCard"), + ("VDim", "vdim", "vDim"), + ("VEmb", "vemb", "vEmb"), + ("XAdd", "xadd", "xAdd"), + ("XRange", "xrange", "xRange"), + ("XRevRange", "xrevrange", "xRevRange"), + ("XLen", "xlen", "xLen"), + ("XDel", "xdel", "xDel"), + ("XTrim", "xtrim", "xTrim"), +] + + +def repo_root() -> Path: + here = Path(__file__).resolve() + for p in here.parents: + if (p / "go.mod").exists() and (p / "api" / "proto" / "cache.proto").exists(): + return p + sys.exit("check-client-surface: repo root not found") + + +def proto_rpcs(proto: Path) -> list[str]: + text = proto.read_text(encoding="utf-8") + service = re.search(r"service Cache \{(?P.*?)\n\}", text, re.S) + if not service: + sys.exit("check-client-surface: service Cache not found") + return re.findall(r"^\s*rpc\s+([A-Za-z0-9_]+)\s*\(", service.group("body"), re.M) + + +def python_sources(root: Path) -> str: + base = root / "clients" / "python" / "src" / "supercache" + parts = [] + for path in sorted(base.rglob("*.py")): + if "_gen" in path.parts: + continue + parts.append(path.read_text(encoding="utf-8")) + return "\n".join(parts) + + +def node_sources(root: Path) -> str: + base = root / "clients" / "node" / "src" + parts = [] + for path in sorted(base.rglob("*.ts")): + if "gen" in path.parts or path.name.endswith(".test.ts"): + continue + parts.append(path.read_text(encoding="utf-8")) + return "\n".join(parts) + + +def has_python(src: str, name: str) -> bool: + return re.search(rf"^\s*def {re.escape(name)}\s*\(", src, re.M) is not None + + +def has_node(src: str, name: str) -> bool: + # A real method, or a CacheApi signature (name followed by '('). + return re.search(rf"\b{re.escape(name)}\s*\(", src) is not None + + +def main() -> int: + root = repo_root() + proto = proto_rpcs(root / "api" / "proto" / "cache.proto") + table = [row[0] for row in SURFACE] + errors = [] + if proto != table: + missing = [name for name in proto if name not in table] + extra = [name for name in table if name not in proto] + if missing: + errors.append("proto RPCs missing from SURFACE: " + ", ".join(missing)) + if extra: + errors.append("SURFACE RPCs not in cache.proto: " + ", ".join(extra)) + if not missing and not extra: + errors.append("SURFACE order does not match service Cache") + py = python_sources(root) + node = node_sources(root) + api = (root / "docs" / "API.md").read_text(encoding="utf-8") + if not py.strip(): + errors.append("Python facade sources are empty") + if not node.strip(): + errors.append("Node facade sources are empty") + for rpc, py_name, node_name in SURFACE: + if py.strip() and not has_python(py, py_name): + errors.append(f"Python facade missing def {py_name} ({rpc})") + if node.strip() and not has_node(node, node_name): + errors.append(f"Node facade missing {node_name} ({rpc})") + if not re.search(rf"\b{re.escape(rpc)}\b", api): + errors.append(f"docs/API.md does not mention {rpc}") + if errors: + print("client surface is behind cache.proto:", file=sys.stderr) + for err in errors: + print(" " + err, file=sys.stderr) + return 1 + print(f"client surface covers {len(proto)} Cache RPCs") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/gen-clients.sh b/scripts/gen-clients.sh new file mode 100644 index 0000000..f3fb272 --- /dev/null +++ b/scripts/gen-clients.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +# Regenerate Python and Node Cache stubs from api/proto/cache.proto. +# +# Pins (do not float these without re-checking the committed stubs): +# protoc 28.3 (libprotoc 28.3) +# grpcio-tools 1.69.0 +# ts-proto 2.7.7 (clients/node devDependency, plugin protoc-gen-ts_proto) +# +# Does not touch api/gen (Go stubs stay on their own generators). +set -euo pipefail + +root=$(cd "$(dirname "$0")/.." && pwd) +cd "$root" + +protoc_ver=$(protoc --version || true) +case "$protoc_ver" in + "libprotoc 28.3") ;; + *) + echo "gen-clients: want protoc 28.3, got ${protoc_ver:-missing}" >&2 + exit 1 + ;; +esac + +if ! python3 -c 'import grpc_tools' >/dev/null 2>&1; then + echo "gen-clients: python module grpc_tools is not installed (grpcio-tools==1.69.0)" >&2 + exit 1 +fi + +plugin="$root/clients/node/node_modules/.bin/protoc-gen-ts_proto" +if [[ ! -x "$plugin" ]]; then + echo "gen-clients: missing $plugin (run npm ci in clients/node)" >&2 + exit 1 +fi + +py_out="$root/clients/python/src/supercache/_gen" +node_out="$root/clients/node/src/gen" +mkdir -p "$py_out" "$node_out" +rm -f "$py_out"/cache_pb2.py "$py_out"/cache_pb2_grpc.py "$py_out"/cache_pb2.pyi \ + "$node_out"/cache.ts + +python3 -m grpc_tools.protoc \ + -I api/proto \ + --python_out="$py_out" \ + --grpc_python_out="$py_out" \ + api/proto/cache.proto + +# grpc_tools emits a top-level import. Make it package-relative. +python3 - "$py_out/cache_pb2_grpc.py" <<'PY' +import pathlib, sys +path = pathlib.Path(sys.argv[1]) +text = path.read_text(encoding="utf-8") +old = "import cache_pb2 as cache__pb2" +new = "from . import cache_pb2 as cache__pb2" +if old not in text: + sys.exit("gen-clients: expected grpc import to rewrite in cache_pb2_grpc.py") +path.write_text(text.replace(old, new, 1), encoding="utf-8") +PY + +if [[ ! -f "$py_out/__init__.py" ]]; then + printf '"""Generated Cache stubs. Do not edit."""\n' > "$py_out/__init__.py" +fi + +protoc \ + -I api/proto \ + --plugin=protoc-gen-ts_proto="$plugin" \ + --ts_proto_out="$node_out" \ + --ts_proto_opt=outputServices=grpc-js,esModuleInterop=true,env=node,useExactTypes=false,forceLong=number,outputIndex=false \ + api/proto/cache.proto + +echo "gen-clients: wrote $py_out and $node_out" From cf1d02712af7bb9e34481b6f732fa5f7231fa766 Mon Sep 17 00:00:00 2001 From: Code0987 <1825861+Code0987@users.noreply.github.com> Date: Thu, 8 Oct 2026 10:57:30 +0000 Subject: [PATCH 2/3] temp: drop Get from the client surface check Proves clients-up-to-date fails when cache.proto and the facade table disagree. Revert after CI shows the failure. --- scripts/check-client-surface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check-client-surface.py b/scripts/check-client-surface.py index 263d717..d13c011 100644 --- a/scripts/check-client-surface.py +++ b/scripts/check-client-surface.py @@ -14,7 +14,7 @@ # (rpc, python method, node method) SURFACE = [ - ("Get", "get", "get"), + # TEMP: Get removed to prove clients-up-to-date fails. Revert this commit. ("Put", "put", "put"), ("PutMany", "put_many", "putMany"), ("Delete", "delete", "delete"), From 80e5bbb7ed1f8b38af738c983ba915f46f160afe Mon Sep 17 00:00:00 2001 From: Code0987 <1825861+Code0987@users.noreply.github.com> Date: Thu, 8 Oct 2026 10:59:18 +0000 Subject: [PATCH 3/3] Revert "temp: drop Get from the client surface check" This reverts commit cf1d02712af7bb9e34481b6f732fa5f7231fa766. --- scripts/check-client-surface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/check-client-surface.py b/scripts/check-client-surface.py index d13c011..263d717 100644 --- a/scripts/check-client-surface.py +++ b/scripts/check-client-surface.py @@ -14,7 +14,7 @@ # (rpc, python method, node method) SURFACE = [ - # TEMP: Get removed to prove clients-up-to-date fails. Revert this commit. + ("Get", "get", "get"), ("Put", "put", "put"), ("PutMany", "put_many", "putMany"), ("Delete", "delete", "delete"),