Synadia.Orbit.KeyValueStore.Extensions
1.0.0-preview.1
Prefix Reserved
dotnet add package Synadia.Orbit.KeyValueStore.Extensions --version 1.0.0-preview.1
NuGet\Install-Package Synadia.Orbit.KeyValueStore.Extensions -Version 1.0.0-preview.1
<PackageReference Include="Synadia.Orbit.KeyValueStore.Extensions" Version="1.0.0-preview.1" />
<PackageVersion Include="Synadia.Orbit.KeyValueStore.Extensions" Version="1.0.0-preview.1" />
<PackageReference Include="Synadia.Orbit.KeyValueStore.Extensions" />
paket add Synadia.Orbit.KeyValueStore.Extensions --version 1.0.0-preview.1
#r "nuget: Synadia.Orbit.KeyValueStore.Extensions, 1.0.0-preview.1"
#:package Synadia.Orbit.KeyValueStore.Extensions@1.0.0-preview.1
#addin nuget:?package=Synadia.Orbit.KeyValueStore.Extensions&version=1.0.0-preview.1&prerelease
#tool nuget:?package=Synadia.Orbit.KeyValueStore.Extensions&version=1.0.0-preview.1&prerelease
KeyValueStore Extensions
Utilities that extend NATS KeyValueStore client functionality.
Key Codecs
Key codecs provide transparent key encoding/decoding for KV stores. This is useful when you need to store keys that contain characters not allowed in NATS subjects, or when you prefer a different key format.
Base64 Key Encoding
Encodes each key token using URL-safe Base64. Useful for keys containing special characters like /, @, or spaces.
// dotnet add package nats.net
// dotnet add package Synadia.Orbit.KeyValueStore.Extensions --prerelease
using Synadia.Orbit.KeyValueStore.Extensions.Codecs;
await using var client = new NatsClient();
var kv = client.CreateKeyValueStoreContext();
var rawStore = await kv.CreateStoreAsync("my-bucket");
var store = rawStore.WithBase64Keys();
// Keys with special characters work transparently
await store.PutAsync("user/123@example.com", "user data");
// Stored in KV as: "dXNlci8xMjNAZXhhbXBsZQ.Y29t"
// ^^^^^^^^^^^^^^^^^^^^^^ ^^^^
// "user/123@example" "com"
// (dots are preserved as token separators, each token is Base64 encoded)
var entry = await store.GetEntryAsync<string>("user/123@example.com");
Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}");
// Output: Key: user/123@example.com, Value: user data
Path-Style Keys
Translates familiar path-style keys (using /) to NATS subject notation (using .).
using Synadia.Orbit.KeyValueStore.Extensions.Codecs;
await using var client = new NatsClient();
var kv = client.CreateKeyValueStoreContext();
var rawStore = await kv.CreateStoreAsync("config-bucket");
var store = rawStore.WithPathKeys();
// Use familiar path-style keys
await store.PutAsync("/config/database/connection-string", "Server=localhost;...");
// Stored in KV as: "_root_.config.database.connection-string"
await store.PutAsync("/config/database/timeout", "30");
// Stored in KV as: "_root_.config.database.timeout"
await store.PutAsync("/config/logging/level", "Information");
// Stored in KV as: "_root_.config.logging.level"
// Keys are returned in path format
await foreach (var key in store.GetKeysAsync())
{
Console.WriteLine(key);
}
// Output:
// /config/database/connection-string
// /config/database/timeout
// /config/logging/level
Chaining Codecs
Multiple codecs can be chained together for complex encoding scenarios.
using Synadia.Orbit.KeyValueStore.Extensions.Codecs;
// Chain: Path codec first, then Base64
var chain = new NatsKeyChainCodec(NatsPathKeyCodec.Instance, NatsBase64KeyCodec.Instance);
var store = rawStore.WithKeyCodec(chain);
Custom Codecs
Implement INatsKeyCodec or INatsFilterableKeyCodec to create custom encoding logic.
using Synadia.Orbit.KeyValueStore.Extensions.Codecs;
public class MyCustomCodec : INatsFilterableKeyCodec
{
public string EncodeKey(string key) => /* your encoding logic */;
public string DecodeKey(string key) => /* your decoding logic */;
public string EncodeFilter(string filter) => /* preserve wildcards */;
}
var store = rawStore.WithKeyCodec(new MyCustomCodec());
Example: Custom Codec (ROT13 'encryption')
using Synadia.Orbit.KeyValueStore.Extensions.Codecs;
await using var client = new NatsClient();
var kv = client.CreateKeyValueStoreContext();
var rawStore = await kv.CreateStoreAsync("secret-bucket");
// Use custom ROT13 codec for "encrypted" keys
var store = rawStore.WithKeyCodec(new Rot13KeyCodec());
// Store with readable keys - they get ROT13 encoded in storage
await store.PutAsync("secret.password", "hunter2");
await store.PutAsync("secret.api-key", "abc123");
// Keys are returned decoded
var entry = await store.GetEntryAsync<string>("secret.password");
Console.WriteLine($"Key: {entry.Key}, Value: {entry.Value}");
// Output: Key: secret.password, Value: hunter2
// But in raw storage, keys are ROT13 encoded
await foreach (string key in rawStore.GetKeysAsync())
{
Console.WriteLine($"Raw Key: {key}");
}
// Output:
// Raw Key: frperg.cnffjbeq
// Raw Key: frperg.ncv-xrl
/// <summary>
/// A custom codec that "encrypts" keys using ROT13 substitution cipher.
/// This is for demonstration purposes only - ROT13 is not secure encryption!
/// </summary>
public class Rot13KeyCodec : INatsFilterableKeyCodec
{
public string EncodeKey(string key) => Rot13(key);
public string DecodeKey(string key) => Rot13(key); // ROT13 is its own inverse
public string EncodeFilter(string filter) => Rot13(filter);
private static string Rot13(string input)
{
var result = new char[input.Length];
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (c >= 'a' && c <= 'z')
{
result[i] = (char)('a' + (c - 'a' + 13) % 26);
}
else if (c >= 'A' && c <= 'Z')
{
result[i] = (char)('A' + (c - 'A' + 13) % 26);
}
else
{
result[i] = c; // Non-letters pass through unchanged (including '.' and '*')
}
}
return new string(result);
}
}
Available Codecs
| Codec | Description |
|---|---|
NatsNoOpKeyCodec |
Pass-through, no encoding |
NatsBase64KeyCodec |
URL-safe Base64 encoding per token |
NatsPathKeyCodec |
Converts /path/style to .subject.style |
NatsKeyChainCodec |
Chains multiple codecs together |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Bcl.AsyncInterfaces (>= 8.0.0)
- NATS.Client.KeyValueStore (>= 2.7.2-preview.1)
- System.Buffers (>= 4.5.1)
- System.Diagnostics.DiagnosticSource (>= 8.0.1)
- System.Memory (>= 4.5.5)
- System.Threading.Channels (>= 8.0.0)
-
.NETStandard 2.1
- NATS.Client.KeyValueStore (>= 2.7.2-preview.1)
- System.Diagnostics.DiagnosticSource (>= 8.0.1)
- System.Threading.Channels (>= 8.0.0)
-
net10.0
- NATS.Client.KeyValueStore (>= 2.7.2-preview.1)
-
net8.0
- NATS.Client.KeyValueStore (>= 2.7.2-preview.1)
-
net9.0
- NATS.Client.KeyValueStore (>= 2.7.2-preview.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-preview.1 | 39 | 1/16/2026 |