diff --git a/src/GameCult.Caching.MessagePack.Generator/CultDocumentMessagePackGenerator.cs b/src/GameCult.Caching.MessagePack.Generator/CultDocumentMessagePackGenerator.cs
index 7a92cdc4..eeb09475 100644
--- a/src/GameCult.Caching.MessagePack.Generator/CultDocumentMessagePackGenerator.cs
+++ b/src/GameCult.Caching.MessagePack.Generator/CultDocumentMessagePackGenerator.cs
@@ -9,10 +9,16 @@ using Microsoft.CodeAnalysis.Text;
namespace GameCult.Caching.MessagePack.Generator
{
- [Generator]
- public sealed class CultDocumentMessagePackGenerator : IIncrementalGenerator
- {
- public void Initialize(IncrementalGeneratorInitializationContext context)
+///
+/// Emits MessagePack payload serializers for CultCache document types.
+///
+[Generator]
+public sealed class CultDocumentMessagePackGenerator : IIncrementalGenerator
+{
+ ///
+ /// Registers the generator pipeline.
+ ///
+ public void Initialize(IncrementalGeneratorInitializationContext context)
{
var documentShapes = context.SyntaxProvider
.CreateSyntaxProvider(
diff --git a/src/GameCult.Caching.MessagePack/CultDocumentMessagePackSerialization.cs b/src/GameCult.Caching.MessagePack/CultDocumentMessagePackSerialization.cs
index b4651c95..4a447433 100644
--- a/src/GameCult.Caching.MessagePack/CultDocumentMessagePackSerialization.cs
+++ b/src/GameCult.Caching.MessagePack/CultDocumentMessagePackSerialization.cs
@@ -7,11 +7,20 @@ using MessagePack.Resolvers;
namespace GameCult.Caching.MessagePack;
+///
+/// MessagePack resolver for CultCache-specific value types.
+///
public sealed class CultDocumentResolver : IFormatterResolver
{
+ ///
+ /// Gets the shared resolver instance.
+ ///
public static readonly CultDocumentResolver Instance = new();
private CultDocumentResolver() { }
+ ///
+ /// Gets a formatter for the requested type, when this resolver owns it.
+ ///
public IMessagePackFormatter? GetFormatter()
{
var type = typeof(T);
@@ -25,12 +34,18 @@ public sealed class CultDocumentResolver : IFormatterResolver
}
}
+///
+/// MessagePack serialization helpers for CultCache documents and backing stores.
+///
public static class CultDocumentMessagePackSerialization
{
private const int PersistedRecordFieldCount = 4;
private const int SchemaCatalogEntryFieldCount = 6;
private const int StoreSnapshotFieldCount = 3;
+ ///
+ /// Gets the shared MessagePack serializer options for CultCache payloads.
+ ///
public static readonly MessagePackSerializerOptions Options =
MessagePackSerializerOptions.Standard
.WithResolver(CompositeResolver.Create(
@@ -38,16 +53,25 @@ public static class CultDocumentMessagePackSerialization
StandardResolver.Instance))
.WithSecurity(MessagePackSecurity.UntrustedData);
+ ///
+ /// Serializes a typed value with the CultCache MessagePack options.
+ ///
public static byte[] Serialize(T value)
{
return MessagePackSerializer.Serialize(value, Options);
}
+ ///
+ /// Deserializes a typed value with the CultCache MessagePack options.
+ ///
public static T Deserialize(byte[] payload)
{
return MessagePackSerializer.Deserialize(payload, Options);
}
+ ///
+ /// Serializes a value whose document type is known at runtime.
+ ///
public static byte[] SerializeUntyped(object value, Type type)
{
if (value != null)
@@ -62,6 +86,9 @@ public static class CultDocumentMessagePackSerialization
return MessagePackSerializer.Serialize(type, value, Options);
}
+ ///
+ /// Deserializes a value whose document type is known at runtime.
+ ///
public static object DeserializeUntyped(Type type, byte[] payload)
{
var descriptor = CultDocumentRegistry.Shared.GetRequired(type);
@@ -73,6 +100,9 @@ public static class CultDocumentMessagePackSerialization
return MessagePackSerializer.Deserialize(type, payload, Options);
}
+ ///
+ /// Serializes one persisted store record.
+ ///
public static byte[] SerializePersistedRecord(CultPersistedRecord record)
{
var buffer = new global::System.Buffers.ArrayBufferWriter();
@@ -82,12 +112,18 @@ public static class CultDocumentMessagePackSerialization
return buffer.WrittenSpan.ToArray();
}
+ ///
+ /// Deserializes one persisted store record.
+ ///
public static CultPersistedRecord DeserializePersistedRecord(byte[] payload)
{
var reader = new MessagePackReader(payload);
return ReadPersistedRecord(ref reader);
}
+ ///
+ /// Serializes a schema catalog.
+ ///
public static byte[] SerializeSchemaCatalog(CultSchemaCatalogEntry[] catalog)
{
var buffer = new global::System.Buffers.ArrayBufferWriter();
@@ -102,6 +138,9 @@ public static class CultDocumentMessagePackSerialization
return buffer.WrittenSpan.ToArray();
}
+ ///
+ /// Deserializes a schema catalog.
+ ///
public static CultSchemaCatalogEntry[] DeserializeSchemaCatalog(byte[] payload)
{
var reader = new MessagePackReader(payload);
@@ -115,6 +154,9 @@ public static class CultDocumentMessagePackSerialization
return catalog;
}
+ ///
+ /// Serializes a complete persisted store snapshot.
+ ///
public static byte[] SerializeSnapshot(CultPersistedStoreSnapshot snapshot)
{
var buffer = new global::System.Buffers.ArrayBufferWriter();
@@ -137,6 +179,9 @@ public static class CultDocumentMessagePackSerialization
return buffer.WrittenSpan.ToArray();
}
+ ///
+ /// Deserializes a complete persisted store snapshot.
+ ///
public static CultPersistedStoreSnapshot DeserializeSnapshot(byte[] payload)
{
var reader = new MessagePackReader(payload);
@@ -282,27 +327,45 @@ public static class CultDocumentMessagePackSerialization
}
}
+///
+/// Single-file CultCache backing store that persists snapshots as MessagePack.
+///
public class SingleFileMessagePackBackingStore : SingleFileBackingStore
{
+ ///
+ /// Creates a MessagePack single-file backing store.
+ ///
public SingleFileMessagePackBackingStore(string filePath) : base(filePath)
{
}
+ ///
+ /// Serializes a store snapshot.
+ ///
protected override byte[] SerializeSnapshot(CultPersistedStoreSnapshot snapshot)
{
return CultDocumentMessagePackSerialization.SerializeSnapshot(snapshot);
}
+ ///
+ /// Deserializes a store snapshot.
+ ///
protected override CultPersistedStoreSnapshot DeserializeSnapshot(byte[] data)
{
return CultDocumentMessagePackSerialization.DeserializeSnapshot(data);
}
+ ///
+ /// Serializes one document payload.
+ ///
protected override byte[] SerializePayload(object document)
{
return CultDocumentMessagePackSerialization.SerializeUntyped(document, document.GetType());
}
+ ///
+ /// Deserializes one document payload.
+ ///
protected override object DeserializePayload(Type documentType, byte[] payload)
{
return CultDocumentMessagePackSerialization.DeserializeUntyped(documentType, payload);
diff --git a/src/GameCult.Caching.MessagePack/CultRecordRefFormatter.cs b/src/GameCult.Caching.MessagePack/CultRecordRefFormatter.cs
index a5f984fc..3348c1c3 100644
--- a/src/GameCult.Caching.MessagePack/CultRecordRefFormatter.cs
+++ b/src/GameCult.Caching.MessagePack/CultRecordRefFormatter.cs
@@ -3,13 +3,22 @@ using MessagePack.Formatters;
namespace GameCult.Caching;
+///
+/// Serializes typed CultCache record references as their persisted key strings.
+///
public sealed class CultRecordRefFormatter : IMessagePackFormatter>
{
+ ///
+ /// Writes a typed record reference to MessagePack.
+ ///
public void Serialize(ref MessagePackWriter writer, CultRecordRef value, MessagePackSerializerOptions options)
{
options.Resolver.GetFormatterWithVerify().Serialize(ref writer, value.Key.Value, options);
}
+ ///
+ /// Reads a typed record reference from MessagePack.
+ ///
public CultRecordRef Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
var key = options.Resolver.GetFormatterWithVerify().Deserialize(ref reader, options) ?? string.Empty;
diff --git a/src/GameCult.Caching/CultCache.cs b/src/GameCult.Caching/CultCache.cs
index 09ec4e81..e4460ebd 100644
--- a/src/GameCult.Caching/CultCache.cs
+++ b/src/GameCult.Caching/CultCache.cs
@@ -13,31 +13,82 @@ using R3;
namespace GameCult.Caching
{
+ ///
+ /// Persisted schema metadata embedded in a CultCache backing store.
+ ///
public sealed class CultSchemaCatalogEntry
{
+ ///
+ /// Gets or sets the content-derived schema identifier.
+ ///
public string SchemaId { get; set; } = string.Empty;
+ ///
+ /// Gets or sets the stable schema name.
+ ///
public string SchemaName { get; set; } = string.Empty;
+ ///
+ /// Gets or sets the schema version string.
+ ///
public string SchemaVersion { get; set; } = string.Empty;
+ ///
+ /// Gets or sets the canonical schema content hash.
+ ///
public string ContentHash { get; set; } = string.Empty;
+ ///
+ /// Gets or sets the canonical schema description.
+ ///
public string CanonicalSchemaJson { get; set; } = string.Empty;
+ ///
+ /// Gets or sets schema identifiers compatible with this entry.
+ ///
public string[] CompatibleSchemaIds { get; set; } = Array.Empty();
}
+ ///
+ /// Persisted serialized document record.
+ ///
public sealed class CultPersistedRecord
{
+ ///
+ /// Gets or sets the persisted record key.
+ ///
public string Key { get; set; } = string.Empty;
+ ///
+ /// Gets or sets the schema identifier used to deserialize the payload.
+ ///
public string SchemaId { get; set; } = string.Empty;
+ ///
+ /// Gets or sets the storage timestamp.
+ ///
public string StoredAt { get; set; } = string.Empty;
+ ///
+ /// Gets or sets the serialized document payload.
+ ///
public byte[] Payload { get; set; } = Array.Empty();
}
+ ///
+ /// Complete snapshot persisted by a single-file CultCache backing store.
+ ///
public sealed class CultPersistedStoreSnapshot
{
+ ///
+ /// Gets or sets the backing store format version.
+ ///
public string FormatVersion { get; set; } = "cultcache.store.v1";
+ ///
+ /// Gets or sets the embedded schema catalog.
+ ///
public CultSchemaCatalogEntry[] SchemaCatalog { get; set; } = Array.Empty();
+ ///
+ /// Gets or sets the persisted records.
+ ///
public CultPersistedRecord[] Records { get; set; } = Array.Empty();
}
+ ///
+ /// Runtime descriptor for a CultCache document type.
+ ///
public sealed class CultDocumentDescriptor
{
internal CultDocumentDescriptor(
@@ -70,20 +121,53 @@ namespace GameCult.Caching
Members = members;
}
+ ///
+ /// Gets the CLR document type.
+ ///
public Type DocumentType { get; }
+ ///
+ /// Gets the stable schema name.
+ ///
public string SchemaName { get; }
+ ///
+ /// Gets the schema version string.
+ ///
public string SchemaVersion { get; }
+ ///
+ /// Gets the content-derived schema identifier.
+ ///
public string SchemaId { get; }
+ ///
+ /// Gets the canonical schema content hash.
+ ///
public string ContentHash { get; }
+ ///
+ /// Gets the canonical schema description.
+ ///
public string CanonicalSchemaJson { get; }
+ ///
+ /// Gets whether this document type stores one global record.
+ ///
public bool IsGlobal { get; }
+ ///
+ /// Gets the document name member, if any.
+ ///
public string? NameMember { get; }
internal Func