CanvaSync.Contracts
0.3.0
dotnet add package CanvaSync.Contracts --version 0.3.0
NuGet\Install-Package CanvaSync.Contracts -Version 0.3.0
<PackageReference Include="CanvaSync.Contracts" Version="0.3.0" />
<PackageVersion Include="CanvaSync.Contracts" Version="0.3.0" />
<PackageReference Include="CanvaSync.Contracts" />
paket add CanvaSync.Contracts --version 0.3.0
#r "nuget: CanvaSync.Contracts, 0.3.0"
#:package CanvaSync.Contracts@0.3.0
#addin nuget:?package=CanvaSync.Contracts&version=0.3.0
#tool nuget:?package=CanvaSync.Contracts&version=0.3.0
@canvasync/contracts
Shared Protocol Buffer contracts for CanvaSync - real-time collaborative whiteboard.
Overview
This package contains:
- Protocol Buffer definitions (
.protofiles) - Generated TypeScript types (npm package)
- Generated C# classes (for .NET API)
Changelog
Release history is tracked in CHANGELOG.md.
Installation
TypeScript/JavaScript (Frontend)
# Option 1: pnpm link (recommended for local dev)
cd canvasync-contracts && pnpm link --global
cd ../canvasync-web && pnpm link --global @canvasync/contracts
# Option 2: npm install (after publishing)
pnpm add @canvasync/contracts
C# (.NET API)
Copy generated files from generated/dotnet/ to your project and add:
dotnet add package Google.Protobuf
📖 For detailed consumption options, see docs/CONSUMING.md
Usage
TypeScript
import {
ClientMessage,
ServerMessage,
StrokePoint,
JoinBoard,
} from "@canvasync/contracts";
// Create a message
const joinMsg: ClientMessage = {
joinBoard: {
boardId: "board-123",
userId: "user-456",
userName: "John",
color: "#FF5733",
},
};
// Encode for WebSocket
const encoded = ClientMessage.encode(joinMsg).finish();
websocket.send(encoded);
// Decode incoming message
const decoded = ServerMessage.decode(new Uint8Array(data));
if (decoded.boardState) {
console.log("Board state received:", decoded.boardState);
}
C#
using CanvaSync.Contracts.Realtime;
using Google.Protobuf;
// Create a message
var msg = new ServerMessage
{
BoardState = new BoardState
{
BoardId = "board-123",
BoardName = "My Whiteboard"
}
};
// Serialize
byte[] bytes = msg.ToByteArray();
// Deserialize
var received = ClientMessage.Parser.ParseFrom(bytes);
if (received.PayloadCase == ClientMessage.PayloadOneofCase.JoinBoard)
{
var join = received.JoinBoard;
Console.WriteLine($"User {join.UserName} joined");
}
Development
Prerequisites
- Node.js 22+
- pnpm
- protoc (Protocol Buffers compiler)
# macOS
brew install protobuf
# Verify
protoc --version
Generate Contracts
# Install dependencies
pnpm install
# Generate TypeScript & C# from proto files
pnpm generate
# Build TypeScript package
pnpm build
Project Structure
canvasync-contracts/
├── proto/ # Source .proto files
│ ├── realtime.proto # WebSocket message types
│ └── events.proto # Kafka event types
├── generated/
│ ├── typescript/ # Generated TS (gitignored)
│ └── dotnet/ # Generated C# (gitignored)
├── dotnet/
│ └── CanvaSync.Contracts/ # .NET NuGet package project
├── src/
│ └── index.ts # Package entry point
├── scripts/
│ ├── generate.sh # Code generation script
│ └── sync-versions.sh # Version sync script
├── docs/
│ ├── CONSUMING.md # How to use in projects
│ └── PUBLISHING.md # How to publish packages
└── package.json
Proto Files
realtime.proto
WebSocket binary protocol messages:
ClientMessage- Messages from browser to serverServerMessage- Messages from server to browser- Drawing types:
StrokeStart,StrokePoint,StrokeEnd - Presence types:
CursorMove,UserJoined,UserLeft
events.proto
Kafka event types for persistence and analytics:
BoardCreatedEvent,BoardDeletedEventStrokeCreatedEvent,StrokeDeletedEventUserJoinedBoardEvent,UserLeftBoardEventBoardActivityEvent(analytics)
License
MIT
| Product | Versions 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. |
-
net10.0
- Google.Protobuf (>= 3.33.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
### Added
- client-to-server message: client sends stroke ID to delete a specific stroke (eraser tool persistence).
- server-to-client broadcast: server notifies all collaborators when a stroke is deleted via eraser.
### Removed
- Removed the hand-authored TypeScript REST DTO export surface from the npm package. is back to being a protobuf/realtime-only boundary.
- Removed the hand-authored REST DTO namespace from the NuGet package source surface. is back to being a protobuf/realtime-only boundary.
### Changed
-
> @canvasync/contracts@0.3.0 build /home/runner/work/canvasync-contracts/canvasync-contracts
> pnpm clean && pnpm generate && tsc
> @canvasync/contracts@0.3.0 clean /home/runner/work/canvasync-contracts/canvasync-contracts
> rm -rf dist generated/typescript/*
> @canvasync/contracts@0.3.0 generate /home/runner/work/canvasync-contracts/canvasync-contracts
> ./scripts/generate.sh
=== CanvaSync Contract Generation ===
Proto dir: /home/runner/work/canvasync-contracts/canvasync-contracts/proto
Output dir: /home/runner/work/canvasync-contracts/canvasync-contracts/generated
Generating C# contracts...
✓ C# files generated
Generating TypeScript contracts...
✓ TypeScript files generated
=== Generation complete ===
C# files: /home/runner/work/canvasync-contracts/canvasync-contracts/generated/dotnet/
TypeScript files: /home/runner/work/canvasync-contracts/canvasync-contracts/generated/typescript/ now cleans before regenerating and compiling so stale REST artifacts cannot survive into published output.
### Breaking
- Consumers importing REST DTO types from must migrate to the API-owned OpenAPI/generated types instead.