Stabilize .NET 10 serialization, streaming, and engine contracts - #123
Merged
Conversation
magiccodingman
marked this pull request as ready for review
August 21, 2026 07:49
This was referenced Aug 21, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This consolidates the useful bug reports and implementation ideas from the open constructor, debug logging, serializer/memory, and framework-upgrade work into one .NET 10 stabilization change. It also addresses additional engine issues found while tracing those paths end to end.
The package version is moved to 3.0.0 because the current package targets
net10.0; applications that must remain on .NET 8 can remain on the 2.x NuGet line.Consumer/API contract
Normal Magic IndexedDB usage is unchanged: service registration,
Query<T>(), database operations, and query composition keep their existing syntax.Public API decisions:
[MagicConstructor]as an opt-in materialization selector.[JsonConstructor]fully supported.ITypedArgument.Serialize(),SerializeToJsonElement(), andSerializeToJsonString()public.Streamserialization overload without removing or changing the existingStreamWriteroverload's encoding behavior.MagicConstructorExceptionfor actionable ambiguous-constructor failures.Constructor precedence is documented and deterministic:
[MagicConstructor];[JsonConstructor];Parameter binding is case-insensitive, optional defaults are honored, read-only constructor-bound properties work, and remaining writable properties are populated after construction. Parameterized nested types no longer fail during cache discovery merely because they lack a parameterless constructor.
Engine corrections
Serialization and interop
System.Text.Jsonwriting.Int32.HashSet<T>, dictionaries, and Magic property names inside nested complex collections.GC.Collect()/finalizer pause.0,false,"", andnullJavaScript results rather than replacing falsey values with{}.Yield streaming and resource lifetime
AsAsyncEnumerable()is progressive rather than fully buffered.DotNetStreamReference,DotNetObjectReference,IJSStreamReference, response streams, and cancellation sources.Runtime and browser helpers
isDebugregistration value to JavaScriptdebugLogat runtime.ReflectionTypeLoadExceptionby using successfully loaded types.closeAll()to close the cached Dexie instances.createDb.How this incorporates the existing work
The existing PRs and Ard's fork surfaced real issues and directly informed this consolidation. The differences below are about preserving the project's longer-term contracts, not dismissing that work.
[JsonConstructor], rejects multiple annotations explicitly, matches parameter names case-insensitively, honors optional defaults, avoids unconditional activation of parameter-only nested types, and keeps a deterministic legacy fallback.debugLoguse. Instead of a module-level constant that remains false,AddMagicBlazorDB(..., isDebug)configures the JavaScript module at runtime.Int32path was not copied because it overflows wider enum backing types and bypasses configured converters. PublicITypedArgumentserialization methods were retained for API stability.Tests
dotnet test Magic.IndexedDb.UnitTests/Magic.IndexedDb.UnitTests.csproj --no-restoredotnet test E2eTest/E2eTest.csproj --no-restoredotnet build Magic.IndexedDb.sln -c Release --no-restoreMagic.IndexedDb.3.0.0.nupkgcontainslib/net10.0and the expected static web assets.The new unit project covers constructor precedence and ambiguity, immutable/hybrid/parameter-only models, optional defaults, public API preservation, escaped JSON, dictionaries, arrays/nested collections/sets, Magic names in nested complex collections, configured enum and simple-type converters, enum expression casts, wire-envelope values including null/false/zero, and chunk reconstruction/completion ordering.
The browser additions cover escaped Unicode and nested values through IndexedDB, a zero count (the falsey-result regression), and the real
AsAsyncEnumerable()transport path.Documentation included and website follow-up
README.mdandMagicIndexDbWiki/Version-3.0-Upgrade.mdnow document the .NET 10/3.0 boundary, constructor behavior, API compatibility, migration status, and progressive-ordering caveat.The hosted documentation should subsequently be aligned in these areas:
[MagicConstructor]example while noting[JsonConstructor]compatibility..Close()/.Delete()examples with the actual async APIs.Query(IndexedDbSet)/QueryOverrideexamples.Skip().Take()examples to the supported query-stage ordering.AsAsyncEnumerable()arrival order.