diff --git a/.github/workflows/build-binaries.yml b/.github/workflows/build-binaries.yml index 2808c822..673b383e 100644 --- a/.github/workflows/build-binaries.yml +++ b/.github/workflows/build-binaries.yml @@ -11,7 +11,7 @@ on: env: YRS_REPO: https://github.com/y-crdt/y-crdt - YRS_BRANCH: release-v0.18.8 + YRS_BRANCH: release-v0.19.1 CARGO_TERM_COLOR: always jobs: diff --git a/Directory.Build.props b/Directory.Build.props index 5a0b13db..2e3a92cc 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -11,7 +11,7 @@ README.md true snupkg - 0.4.0 + 0.4.1 diff --git a/Tests/YDotNet.Tests.Unit/Maps/InsertTests.cs b/Tests/YDotNet.Tests.Unit/Maps/InsertTests.cs index 73e9b761..ddb08fa8 100644 --- a/Tests/YDotNet.Tests.Unit/Maps/InsertTests.cs +++ b/Tests/YDotNet.Tests.Unit/Maps/InsertTests.cs @@ -328,6 +328,35 @@ public void InsertDifferentTypeOnExistingKey() Assert.That(length, Is.EqualTo(expected: 1)); } + [Test] + public void InsertNestedMap() + { + // Arrange + var doc = new Doc(); + var map = doc.Map("map"); + + // Act + var transaction = doc.WriteTransaction(); + + var innerMap = Input.Map(new Dictionary + { + { "text", Input.String("Nested data") } + }); + + var outerMap = Input.Map(new Dictionary + { + { "innerMap", innerMap } + }); + + map.Insert(transaction, "outerMap", outerMap); + var length = map.Length(transaction); + + transaction.Commit(); + + // Assert + Assert.That(length, Is.EqualTo(expected: 1)); + } + private (Doc, Map) ArrangeDoc() { var doc = new Doc(); diff --git a/Tests/YDotNet.Tests.Unit/UndoManagers/AddScopeTests.cs b/Tests/YDotNet.Tests.Unit/UndoManagers/AddScopeTests.cs index b9b98fe6..893b13f3 100644 --- a/Tests/YDotNet.Tests.Unit/UndoManagers/AddScopeTests.cs +++ b/Tests/YDotNet.Tests.Unit/UndoManagers/AddScopeTests.cs @@ -39,4 +39,35 @@ public void StartsTrackingAfterAddingScope() // Assert Assert.That(undoEvent, Is.Not.Null); } + + [Test] + public void StartsTrackingAfterAddingScopeWithoutDefaultScope() + { + // Arrange + var doc = new Doc(); + var array = doc.Array("array"); + var undoManager = new UndoManager(doc, new UndoManagerOptions { CaptureTimeoutMilliseconds = 0 }); + + UndoEvent? undoEvent = null; + undoManager.ObserveAdded(e => undoEvent = e); + + // Act + undoEvent = null; + var transaction = doc.WriteTransaction(); + array.InsertRange(transaction, index: 0, new[] { Input.Long(value: 2469L) }); + transaction.Commit(); + + // Assert + Assert.That(undoEvent, Is.Null); + + // Act + undoEvent = null; + undoManager.AddScope(array); + transaction = doc.WriteTransaction(); + array.InsertRange(transaction, index: 1, new[] { Input.Boolean(value: false) }); + transaction.Commit(); + + // Assert + Assert.That(undoEvent, Is.Not.Null); + } } diff --git a/YDotNet/Document/UndoManagers/UndoManager.cs b/YDotNet/Document/UndoManagers/UndoManager.cs index 3ff22a6e..e3c47b12 100644 --- a/YDotNet/Document/UndoManagers/UndoManager.cs +++ b/YDotNet/Document/UndoManagers/UndoManager.cs @@ -17,13 +17,23 @@ public class UndoManager : UnmanagedResource private readonly EventSubscriber onAdded; private readonly EventSubscriber onPopped; + /// + /// Initializes a new instance of the class without a scope. + /// + /// The to operate over. + /// The options to initialize the . + public UndoManager(Doc doc, UndoManagerOptions? options = null) + : this(doc, null, options) + { + } + /// /// Initializes a new instance of the class. /// /// The to operate over. - /// The shared type in the to operate over. + /// The shared type in the to operate over. To be added as a default scope.. /// The options to initialize the . - public UndoManager(Doc doc, Branch branch, UndoManagerOptions? options = null) + public UndoManager(Doc doc, Branch? branch, UndoManagerOptions? options = null) : base(Create(doc, branch, options)) { onAdded = new EventSubscriber( @@ -186,10 +196,17 @@ protected override void DisposeCore(bool disposing) UndoManagerChannel.Destroy(Handle); } - private static nint Create(Doc doc, Branch branch, UndoManagerOptions? options) + private static nint Create(Doc doc, Branch? branch, UndoManagerOptions? options) { var unsafeOptions = MemoryWriter.WriteStruct(options?.ToNative() ?? default); - return UndoManagerChannel.NewWithOptions(doc.Handle, branch.Handle, unsafeOptions.Handle); + var handle = UndoManagerChannel.NewWithOptions(doc.Handle, unsafeOptions.Handle); + + if (branch != null) + { + UndoManagerChannel.AddScope(handle, branch.Handle); + } + + return handle; } } diff --git a/YDotNet/Native/UndoManager/UndoManagerChannel.cs b/YDotNet/Native/UndoManager/UndoManagerChannel.cs index 081b9463..a40b2785 100644 --- a/YDotNet/Native/UndoManager/UndoManagerChannel.cs +++ b/YDotNet/Native/UndoManager/UndoManagerChannel.cs @@ -12,7 +12,7 @@ internal static class UndoManagerChannel ChannelSettings.NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "yundo_manager")] - public static extern nint NewWithOptions(nint doc, nint branch, nint options); + public static extern nint NewWithOptions(nint doc, nint options); [DllImport( ChannelSettings.NativeLib,