Skip to content

Releases: Cratis/Arc

Release v20.12.0

30 Apr 21:46
c40826f

Choose a tag to compare

Added

  • IInterceptReadModel<TReadModel> interface for implementing cross-cutting read model interceptors (decryption, masking, etc.) (#2152)
  • IReadModelInterceptors applied consistently across model-bound queries, controller-based queries (QueryActionFilter), and all observable streaming paths (ClientObservable, ClientObservableSSE, ClientEnumerableObservable, ClientEnumerableObservableSSE) (#2152)
  • Interceptors are discovered via ITypes at startup and resolved from IServiceProvider per request, supporting scoped and transient lifetimes (#2152)

Release v20.11.1

29 Apr 12:38

Choose a tag to compare

No release notes

Release v20.11.0

29 Apr 11:38
cdb7a74

Choose a tag to compare

Changed

  • Proxy generator now emits ValueMap<K, V> (with @field(ValueMap) and the corresponding @cratis/fundamentals import) for IDictionary properties with non-string keys, replacing the previous Map<K, V>. ValueMap uses value-based key equality, which is required when key instances are reconstructed across serialization boundaries.

Added

  • Package upgrades: Cratis.Fundamentals / Cratis.Metrics.Roslyn 7.7.6 → 7.8.0, Cratis.Chronicle 15.18.17 → 15.18.20, @cratis/fundamentals 7.7.1 → 7.8.0, plus routine bumps for TypeScript, Vite, Vitest, ESLint, React, and several NuGet packages.

Release v20.10.10

28 Apr 20:08
3076e25

Choose a tag to compare

Reverts all NativeAOT-specific changes introduced in #2180, restoring IInstancesOf<T> throughout Arc.Core. Retains only the fix for using the correct type name when constructing ModelBoundQueryPerformer.FullyQualifiedName from generated metadata.

Changed

  • Restored IInstancesOf<T> in Authentication, AuthorizationEvaluator, CommandContextValuesBuilder, CommandFilters, CommandHandlerProviders, CommandResponseValueHandlers, QueryFilters, and QueryPerformerProviders
  • Reverted spec files back to KnownInstancesOf<T> construction instead of plain array literals

Removed

  • Explicit TryAddSingleton/AddSingleton registrations for Arc.Core-owned services from CommandServiceCollectionExtensions, QueryServiceCollectionExtensions, and HostBuilderExtensions
  • [DynamicDependency] attributes from QueryMetadataGenerator generated initializer and IntrospectionEndpointMapper
  • AOT project properties (PublishAot, TreatAsLocalProperty, GlobalPropertiesToRemove, IlcArg items) from Arc.Core.CodeAnalysis.csproj, Arc.Core.Generators.csproj, Arc.Core.csproj, and ArcCore.csproj
  • publish:aot:mangled script from TestApps/ArcCore/package.json and the accompanying README.md

Release v20.10.9

28 Apr 19:47
a587ceb

Choose a tag to compare

Reverts all NativeAOT-specific changes introduced in #2180, restoring IInstancesOf<T> throughout Arc.Core. Retains only the fix for using the correct type name when constructing ModelBoundQueryPerformer.FullyQualifiedName from generated metadata.

Changed

  • Restored IInstancesOf<T> in Authentication, AuthorizationEvaluator, CommandContextValuesBuilder, CommandFilters, CommandHandlerProviders, CommandResponseValueHandlers, QueryFilters, and QueryPerformerProviders
  • Reverted spec files back to KnownInstancesOf<T> construction instead of plain array literals

Removed

  • Explicit TryAddSingleton/AddSingleton registrations for Arc.Core-owned services from CommandServiceCollectionExtensions, QueryServiceCollectionExtensions, and HostBuilderExtensions
  • [DynamicDependency] attributes from QueryMetadataGenerator generated initializer and IntrospectionEndpointMapper
  • AOT project properties (PublishAot, TreatAsLocalProperty, GlobalPropertiesToRemove, IlcArg items) from Arc.Core.CodeAnalysis.csproj, Arc.Core.Generators.csproj, Arc.Core.csproj, and ArcCore.csproj
  • publish:aot:mangled script from TestApps/ArcCore/package.json and the accompanying README.md

Release v20.10.8

28 Apr 18:28
c59b754

Choose a tag to compare

Summary

Fixes /.cratis/queries (and other introspection endpoints) returning empty arrays under NativeAOT.

Root cause: Under NativeAOT, DependencyContext.Load(entryAssembly) returns null, causing Types.Instance.All to be empty. IInstancesOf<T> resolves to an empty collection, so no Arc.Core services were properly wired.

Changes

  • Replaced IInstancesOf<T> with IEnumerable<T> in all Arc.Core service constructors (Authentication, AuthorizationEvaluator, CommandContextValuesBuilder, CommandFilters, CommandHandlerProviders, CommandResponseValueHandlers, QueryFilters, QueryPerformerProviders) — standard DI works correctly under NativeAOT
  • Added explicit TryAddSingleton/AddSingleton registrations for all Arc.Core-owned service implementations in AddCratisArcCore(), AddCratisCommands(), and AddCratisQueries() so the framework self-registers without relying on convention scanning
  • Added [DynamicDependency] attributes to the [ModuleInitializer] emitted by QueryMetadataGenerator to preserve read model types from NativeAOT trimming
  • Added [DynamicDependency] attributes to IntrospectionEndpointMapper for CommandIntrospectionMetadata, QueryIntrospectionMetadata, and QueryResult
  • Cleaned up TestApps/ArcCore/Program.cs — all manual workaround registrations removed; app is now clean
  • Updated specs to use array literals instead of KnownInstancesOf<T>

Release v20.10.7

28 Apr 15:20
c59b754

Choose a tag to compare

Fixed

  • Fix model-bound queries created from generated metadata so they keep the generated fully qualified query name.
  • Add NativeAOT mangled publish support for the ArcCore test app.

Release v20.10.6

28 Apr 11:06
0a4fb8e

Choose a tag to compare

Fixed

  • Fixing removal of items identified by Guid for delta versions of observable queries. The removal was issued from the backend, but the frontend never removed them.

Release v20.10.5

28 Apr 09:03
f56ae65

Choose a tag to compare

Fixed

  • Observable query response data is now properly deserialized for all transfer modes, fixing Guid fields and other strongly-typed fields losing their methods (#2173)

Summary

The initial fix (PR #2176) only addressed delta mode changeSet deserialization, but the root cause affects all observable query responses, not just delta updates.

The Problem

When observable query responses arrive from the server, the data is transmitted as plain JSON objects. The code was never deserializing this data into model instances with their @field decorators applied. This caused:

  • Guid fields to lose their .equals() method
  • DateTime fields to be plain strings instead of Date instances
  • Other strongly-typed fields to lack their methods
  • Downstream components (like ChecklistValidation) to crash when calling methods

Root Cause

The issue exists in ALL response paths:

  1. Initial response with full data array — QueryResultWithState.fromQueryResult() just passes data through without deserializing
  2. Subsequent full-data responses (non-delta mode) — Same issue
  3. Delta mode with changeSet items — The changeSet items were deserialized in PR #2176, but...
  4. Delta mode fallback (no previous result) — Falls back to un-deserialized data

The Fix

Added deserializeResponseData() function that:

  • Checks if data is an array and modelType is available
  • Calls JsonSerializer.deserializeArrayFromInstance() to instantiate all items with proper types
  • Covers all response paths in the subscription callback

Now all response data, regardless of transfer mode, is properly instantiated with @field decorators applied and methods available.

Testing

  • Existing regression test from PR #2176 still passes
  • All adjacent observable query tests pass
  • Full Release build succeeds without warnings

Release v20.10.4

28 Apr 08:54
a48fd02

Choose a tag to compare

Fixed

  • Guid fields in observable query items now retain their methods (like .equals()) when reconstructed from change sets in delta mode (#2173)

Summary

Commit b52ecba introduced delta change-set optimization to reduce bandwidth by only sending items that were added, replaced, or removed since the last update. However, the change-set items were not being deserialized into typed model instances, causing Guid fields (and other strongly-typed fields) to remain as plain JSON objects and lose their methods.

This fix adds deserialization of all change-set items (added, replaced, removed) using JsonSerializer.deserializeArrayFromInstance before applying delta reconstruction in useObservableQuery, ensuring Guid fields are properly instantiated and methods like .equals() work correctly.

The fix includes a regression test that reproduces the exact failure scenario and ensures this issue doesn't regress in the future.