Bit.Bcrdt.Bink 11.0.0-pre-18

This is a prerelease version of Bit.Bcrdt.Bink.
dotnet add package Bit.Bcrdt.Bink --version 11.0.0-pre-18
                    
NuGet\Install-Package Bit.Bcrdt.Bink -Version 11.0.0-pre-18
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Bit.Bcrdt.Bink" Version="11.0.0-pre-18" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Bit.Bcrdt.Bink" Version="11.0.0-pre-18" />
                    
Directory.Packages.props
<PackageReference Include="Bit.Bcrdt.Bink" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Bit.Bcrdt.Bink --version 11.0.0-pre-18
                    
#r "nuget: Bit.Bcrdt.Bink, 11.0.0-pre-18"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Bit.Bcrdt.Bink@11.0.0-pre-18
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Bit.Bcrdt.Bink&version=11.0.0-pre-18&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Bit.Bcrdt.Bink&version=11.0.0-pre-18&prerelease
                    
Install as a Cake Tool

Bit.Bcrdt.Bink

bit Bcrdt as the collaboration backend for bit Bink: several people drawing on one BinkDocument, with offline editing, reconnection, persistence, presence and selective undo coming from Bcrdt instead of Bink's own BinkCollaborationSession.

dotnet add package Bit.Bcrdt.Bink
<BinkCanvas @ref="_canvas" Document="_drawing" />

@code {
    [CascadingParameter] public BcrdtCollaborativeDocument Document { get; set; } = default!;

    private readonly BinkDocument _drawing = new();
    private BinkCanvas? _canvas;
    private BcrdtBinkBinding? _binding;

    protected override void OnAfterRender(bool firstRender)
    {
        if (!firstRender) return;
        _binding = new BcrdtBinkBinding(Document.Crdt.GetMap("drawing"), _drawing, new BcrdtBinkBindingOptions
        {
            History = _canvas!.History,       // one transaction per gesture
            Presence = Document.Presence,      // optional: cursors and selections
            Selection = _canvas.Selection,
        });
    }

    public void Dispose() => _binding?.Dispose();
}

How the drawing is shared

Every layer and every element is an entry of its own in the bound map, keyed by its identifier - l:{id} and e:{id}, each a nested map - holding the object's properties in Bink's own file format, one key per property. Page settings are s:width, s:height and s:background; document metadata is m:{key}.

  • Different elements never conflict. Two people drawing, moving or deleting different elements touch different entries, and a deletion is by identifier, never by position.
  • Different properties of one element both survive. One person moving a shape while another recolours it keeps both, because the transform and the style are different keys. Two changes to the same property resolve to one of them, the same one on every replica.
  • A finished stroke's points are one value. They never change after the pen lifts, so there is nothing to merge.
  • Stacking order and layer membership are fields. Each entry carries $order, a fractional order key (BcrdtOrderKey, the keys BcrdtOrderedCollection uses) its neighbours are sorted by (ties broken by identifier), and an element carries $layer. Bringing an element to the front or moving it to another layer is one field write, so concurrent reorders converge on one order instead of Bink's index-based operations leaving replicas stacked differently. There is always room for another key between two, so nothing is ever renumbered.
  • A deleted layer takes its elements with it, including any a collaborator drew into it concurrently: such an element stays in the shared state but no replica shows it.

Gestures, echoes and origins

The binding listens to BinkDocument.Changed. With History set, changes are held until the history records a step, so a drag of sixty frames is one transaction, one update on the wire and one undo step; without it every change is written as it is reported. Each transaction is tagged with Origin (the binding itself unless you give one).

Everything else that changes the map - a collaborator, an undo, your own code - is applied to the drawing as one batch with BinkChangeOrigin.Remote, which Bink's history does not record and the binding does not write back. Changes with BinkChangeOrigin.Load are not written either, as Bink's own collaboration session does not send them.

An element this participant is still changing keeps its unwritten properties when a collaborator's change to the same element arrives; only the properties that change touched are taken from it.

Joining and starting

Binding to a map that already holds a drawing replaces the document's content with it. Binding a document with content - elements, a second layer, metadata - to an empty map writes it there, in one transaction. A new, empty document writes nothing and shows the shared default layer, BcrdtBinkBinding.DefaultLayerId, so two people opening a new drawing draw into the same layer rather than each into their own.

Undo

CreateUndoManager() returns a BcrdtUndoManager scoped to the bound map and tracking the binding's origin: it undoes this participant's changes and nobody else's, property by property. Bink's own history keeps working beside it, and its undo is written like any other change - but it restores whole elements, so undoing a move of a shape somebody has since recoloured restores the old colour too. Use one or the other for a drawing.

Presence

With Presence set, PublishCursor and PublishSelection (automatic when Selection is given) publish under the bink presence field, and Participants reads everybody else's cursor and selection.

Limits

  • Properties a newer Bink writes and an older one cannot read are dropped from an element when the older one edits it, as with Bink's own collaboration.
  • An element that breaks this replica's BinkDocumentLimits, or cannot be read, is left out of its drawing and reported through RemoteChangeRejected; it stays in the shared state for the replicas that can show it.
  • A stroke in progress is not shared - only finished ones are. Live ink belongs in presence.

The full guide is in the Bcrdt README.

Product Compatible and additional computed target framework versions.
.NET 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.  net11.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
11.0.0-pre-18 0 11/12/2026