Disruptor.Surreal 1.0.0

dotnet add package Disruptor.Surreal --version 1.0.0
                    
NuGet\Install-Package Disruptor.Surreal -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Disruptor.Surreal" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Disruptor.Surreal" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Disruptor.Surreal" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Disruptor.Surreal --version 1.0.0
                    
#r "nuget: Disruptor.Surreal, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Disruptor.Surreal@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Disruptor.Surreal&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Disruptor.Surreal&version=1.0.0
                    
Install as a Cake Tool

Disruptor.Surreal

A .NET 10 client for SurrealDB, modeled on the official Rust client. CBOR over WebSocket. Single package. No embedded mode.

Unofficial. Not affiliated with the SurrealDB project. The Disruptor.Surreal name keeps that unambiguous. MIT; contributions welcome.

Why this exists

Targeted to our design goals — not intended as a general-purpose drop-in replacement for the official SDK.

(yet. evil laugh.)

Built alongside Disruptor.Surface, an ORM/source-generator project whose transport needs drive the v1 surface here: CBOR over WS, typed bindings, server-side transactions, faithful Value-tree round-tripping for SurrealDB's wire types (RecordId, decimal, DateTimeOffset, Guid, Datetime / Duration with full nanosecond precision). Embedded is permanently out — we trust the database.

Install

The project targets net10.0. Install from NuGet:

dotnet add package Disruptor.Surreal

or add a PackageReference:

<PackageReference Include="Disruptor.Surreal" Version="1.0.0" />

Quick start

using Disruptor.Surreal;
using Disruptor.Surreal.Connection;
using Disruptor.Surreal.Values;

// One-shot connect: parse the connection string, dial WS, signin, switch ns/db.
await using var db = await SurrealClient.ConnectAsync(SurrealOptions.Parse(
    "Url=ws://localhost:8000;Namespace=test;Database=test;User=root;Password=root"));

var jaime = new SurrealRecordId("person", "jaime");

// Create a record at a known id
await db.CreateAsync(jaime, new SurrealObject
{
    ["name"] = "Jaime",
    ["age"] = 30L,
    ["joined"] = DateTimeOffset.UtcNow,   // CBOR tag 12
    ["balance"] = 1234.56m,                // CBOR tag 10
    ["session"] = Guid.NewGuid(),          // CBOR tag 37
});

// Multi-statement query with bindings
var response = await db.QueryAsync(
    "SELECT * FROM person WHERE age >= $minAge",
    new SurrealObject { ["minAge"] = 21L });
var rows = response.Take(0);  // SurrealValue (a SurrealListValue of SurrealObjectValue)

// Server-side transaction with rollback
await using var tx = await db.BeginTransactionAsync();
await tx.UpdateAsync(jaime, new SurrealObject { ["balance"] = 9999m });
await tx.CommitAsync();   // or tx.CancelAsync() to roll back

Wire format

CBOR over WebSocket using the SurrealDB-flavoured tag scheme:

Tag Meaning .NET surface
0 Spec datetime (text) decode-only
6 NONE sentinel SurrealNoneValue
7 Table reference SurrealTable / SurrealTableValue
8 RecordId [table, key] SurrealRecordId / SurrealRecordIdKey
9 UUID (text) decode-only
10 Decimal (text, canonical) decimal
12 Datetime [seconds, nanos] SurrealDateTime ↔ DateTimeOffset
13 Duration (text) decode-only
14 Duration [secs?, nanos?] SurrealDuration ↔ TimeSpan
37 UUID (16-byte big-endian) Guid

Datetimes preserve full nanosecond precision via an explicit Nanos field (since DateTimeOffset only resolves to 100ns ticks).

Feature matrix

Compared against the official Rust client as the de-facto reference implementation. (Status legend: yes = supported, no = open work, partial = some sub-features only, out = permanently out of scope, n/a = no wire representation in the protocol.)

Transports

Transport Rust Disruptor.Surreal Notes
WebSocket (ws, wss) yes yes CBOR sub-protocol
HTTP / HTTPS yes out WS-only by design — single transport path, type-preserving CBOR, live queries possible
Embedded mem yes out We trust the database
Embedded rocksdb yes out —
Embedded surrealkv yes out —
Embedded file yes out —
Embedded indxdb (WASM) yes out —
Distributed tikv yes out —

Wire format

Format Rust Disruptor.Surreal Notes
CBOR yes yes Via System.Formats.Cbor
JSON partial out Server supports it; lossy for record-id / datetime / decimal types — we won't add it
Flatbuffers yes (default) out Rust client's current default; brings an IDL/codegen workflow we don't want

RPC methods

Method Rust Disruptor.Surreal
use_ns / use_db yes yes
signin / signup yes yes
authenticate / invalidate yes yes
refresh (rotate token) yes yes — RefreshAsync; mirrors Rust Command::Refresh
set / unset (session vars) yes yes
query (with bindings) yes yes
select (table or RecordId) yes yes
create (table or RecordId, with content) yes yes
update (table or RecordId) yes yes
delete (table or RecordId) yes yes
upsert (table or RecordId) yes yes
merge (table or RecordId) yes yes
patch (JSON-Patch ops) yes yes — see Patch.Add/Replace/Remove/Move/Copy/Test/Change helpers
insert (single or bulk) yes yes
insert_relation (single or bulk edges) yes yes
relate (graph edge) yes yes
run (server-side function, optional version) yes yes
version / ping (health) yes yes
begin / commit / cancel (txn id) yes yes
live / kill (live queries) yes yes (LiveAsync returns a SurrealLiveQueryHandle : IAsyncEnumerable<SurrealNotification>; DroppedCount exposes back-pressure-induced loss)
export / import yes out — server-side these are HTTP endpoints (/export, /import), not RPC methods; out of scope alongside the HTTP transport
ML model export yes out

Auth credentials

Credential Rust Disruptor.Surreal
Root yes yes
Namespace yes yes
Database yes yes
Record (scope, params object) yes yes
Access token (bearer) yes yes
Refresh token / rotation yes yes (SurrealToken { SurrealAccess, Refresh? }, RefreshAsync)

Value tree

Variant CBOR tag Rust Disruptor.Surreal
None / Null / Bool 6 / — yes yes
Number (Int / Float / Decimal) — / — / 10 yes yes
String / Bytes — / — yes yes
Datetime (full nanosecond precision) 0 / 12 yes yes (SurrealDateTime)
Duration 13 / 14 yes yes (SurrealDuration)
Uuid 9 / 37 yes yes
Table 7 yes yes (SurrealTable)
RecordId (string / int / uuid / ulid keys) 8 yes yes (SurrealRecordId, Surreal{String,Integer,Uuid,Ulid,List,Object,Range}RecordIdKey)
Array / Object — / — yes yes (SurrealList, SurrealObject)
Set 56 yes yes (SurrealSet, SurrealSetValue)
Range / RecordIdKeyRange 49 / 50 / 51 yes yes (SurrealRange, SurrealBound<T>, RecordIdKeyRange, SurrealRangeRecordIdKey)
Geometry (Point/Line/Polygon/Multi*/Collection) 88–94 yes yes (SurrealGeometry.Point/Line/Polygon/MultiPoint/MultiLine/MultiPolygon/Collection)
File (bucket reference) 55 yes yes (SurrealFile, SurrealFileValue)
Regex — yes n/a — Rust source explicitly errors on CBOR encoding for regex (convert.rs:450); no wire shape exists

Connection lifecycle

Feature Rust Disruptor.Surreal
Connection-string parsing yes yes (ADO-style)
One-shot connect + signin + use_ns/db n/a yes
Auto re-auth on token expiry (transparent retry) yes yes
Reconnect with session replay (outside txn) yes out — explicit drop = explicit reconnect; we don't paper over connection state for the consumer
Server version compatibility check yes yes (>=3.0.0-alpha.1, <4.0.0; opt out via SurrealConnectionConfig.SkipVersionCheck)
Multi-session per connection yes out — one SurrealClient instance owns its WS 1:1; spin up a second for a second session

Error / diagnostics

Feature Rust Disruptor.Surreal
Typed exception hierarchy yes yes (Auth / Conflict / TransactionAborted / Constraint / Connection / Protocol / Rpc)
Token-expiry signal yes yes (SurrealAuthException.IsTokenExpired)
Retry-on-conflict helper n/a yes (SurrealRetryPolicy.WithRetryAsync)

Consumer-side mapping

Feature Rust Disruptor.Surreal
ISurrealRecordId interop interface yes (Sealed trait) yes
POCO mapping (attribute / source-gen / reflection) yes (SurrealValue derive) out — consumer brings the mapper

Layout

src/Disruptor.Surreal/         — the library (one package)
  Auth/                          — credentials + SurrealAccessToken
  Cbor/                          — tag table, reader, writer
  Connection/                    — SurrealEndpoint, Command, Rpc{Request,Response},
                                   ISurrealConnection, SurrealWebSocketConnection,
                                   SurrealOptions, SurrealConnectionConfig,
                                   ServerVersion
  Errors/                        — exception hierarchy
  Live/                          — SurrealLiveQueryHandle, SurrealNotification,
                                   SurrealLiveQueryOptions
  Query/                         — SurrealQueryResponse, SurrealQueryStatement
  Values/                        — Value tree + scalar wrappers
                                   (SurrealDateTime, SurrealDuration, etc.)
                                   + ISurrealRecordId
  Patch.cs                       — JSON-Patch op factories
  SurrealClient.cs               — main client class
  SurrealRetryPolicy.cs          — retry-on-conflict helper
  SurrealTransaction.cs          — transaction handle (auto-cancel on dispose)
tests/Disruptor.Surreal.Tests/   — xUnit (CBOR roundtrip, endpoint parsing,
                                   value semantics, error classifier,
                                   options parsing)
samples/Disruptor.Surreal.Sample/ — runnable demo

Run the tests

dotnet test

Run the sample (needs a local server)

docker run -d --rm --name surrealdb -p 8000:8000 surrealdb/surrealdb:latest \
  start --user root --pass root memory
dotnet run --project samples/Disruptor.Surreal.Sample

License

MIT. See LICENSE.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Disruptor.Surreal:

Package Downloads
Disruptor.Surface.Runtime

Runtime types for Disruptor.Surface — typed RecordId structs, SurrealSession, relation markers, hydration helpers, and query primitives. Pair with Disruptor.Surface.Generator (analyzer-style PackageReference) to drive [Table]-based code generation.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 159 7/3/2026
0.1.0-preview.11 136 5/13/2026 0.1.0-preview.11 is deprecated because it is no longer maintained.