diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b073372..592258d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,8 +2,6 @@ name: build+test on: push: - branches: - - dev env: CARGO_TERM_COLOR: always diff --git a/Cargo.lock b/Cargo.lock index 24d7fab..24f8811 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,7 +96,8 @@ checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "codemp-proto" -version = "0.7.2" +version = "0.8.0" + dependencies = [ "prost", "tonic", diff --git a/Cargo.toml b/Cargo.toml index 9da5fa8..aa33c85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ authors = [ "cschen " ] license = "GPL-3.0-only" -version = "0.7.2" +version = "0.8.0" edition = "2024" [lib] diff --git a/proto/buffer.proto b/proto/buffer.proto index 6947e8b..475f0d2 100644 --- a/proto/buffer.proto +++ b/proto/buffer.proto @@ -8,6 +8,8 @@ package buffer; service Buffer { // Attach to a buffer and receive operations. rpc Attach (stream Operation) returns (stream BufferEvent); + // Kicks all active users from the buffer. + rpc KickAll (common.Empty) returns (common.Empty); } // Message representing an operation that has occurred. @@ -21,5 +23,5 @@ message BufferEvent { // The operation that occurred. required Operation op = 1; // The user that sent this event. - required common.Identity user = 2; + required common.Identifier user = 2; } diff --git a/proto/common.proto b/proto/common.proto index 172fc7f..4419aee 100644 --- a/proto/common.proto +++ b/proto/common.proto @@ -8,7 +8,7 @@ message Token { } // Message representing a UUID. -message Identity { +message Identifier { // The most significant bits of the UUID. required uint64 hi = 1; // The least significant bits of the UUID. @@ -18,10 +18,20 @@ message Identity { // Message representing a user. message User { // The UUID of the user. - required Identity id = 1; + required Identifier id = 1; // The name of a user. required string name = 2; } +// Message representing a workspace. +message WorkspaceInfo { + // The UUID of the workspace. + required Identifier id = 1; + // The owner of the workspace, for easy namespacing. + required User owner = 2; + // Mnemonical name of the workspace. + required string name = 3; +} + // A generic empty message. message Empty { } diff --git a/proto/cursor.proto b/proto/cursor.proto index 320de1d..a9c72a7 100644 --- a/proto/cursor.proto +++ b/proto/cursor.proto @@ -6,10 +6,18 @@ import "files.proto"; // Handles cursor events and broadcasts them to all users. service Cursor { + // Retrieves all current cursor positions. + rpc List(common.Empty) returns (CursorEventList); // Subscribe to a workspace's cursor events. rpc Attach (stream cursor.CursorPosition) returns (stream cursor.CursorEvent); } +// A message representing a list of cursor events. +message CursorEventList { + // A vector of cursor events. + repeated CursorEvent cursors = 1; +} + // A message representing a position in a buffer. message RowCol { // The row. @@ -31,7 +39,7 @@ message CursorPosition { // A message representing a cursor event. message CursorEvent { // The user moving the cursor. - required common.Identity user = 1; + required common.Identifier user = 1; // The new cursor position. - required CursorPosition position = 2; + repeated CursorPosition position = 2; } diff --git a/proto/files.proto b/proto/files.proto index 055ea72..435dbf6 100644 --- a/proto/files.proto +++ b/proto/files.proto @@ -2,10 +2,18 @@ syntax = "proto2"; package files; +// A message representing a buffer request. +message BufferRequest { + // The path of a buffer. + required string path = 1; +} + // A message representing a node in the filetree. message BufferNode { // The path of a buffer. required string path = 1; + // Whether the buffer is ephemeral; + required bool ephemeral = 2; } // A message representing a filetree. diff --git a/proto/session.proto b/proto/session.proto index 39996c1..2f97fcf 100644 --- a/proto/session.proto +++ b/proto/session.proto @@ -6,36 +6,87 @@ import "common.proto"; // Manages user workspaces and refreshes tokens. service Session { + // Attach to a session and receive events. + rpc Attach (common.Empty) returns (stream SessionEvent); // Handle a workspace access request and return a workspace token. rpc AccessWorkspace (WorkspaceRequest) returns (common.Token); // Create a workspace. - rpc CreateWorkspace (WorkspaceRequest) returns (common.Empty); + rpc CreateWorkspace (OwnedWorkspaceRequest) returns (common.WorkspaceInfo); // Delete a workspace. - rpc DeleteWorkspace (WorkspaceRequest) returns (common.Empty); - // List all available workspaces. - rpc ListWorkspaces (common.Empty) returns (WorkspaceList); + rpc DeleteWorkspace (OwnedWorkspaceRequest) returns (common.Empty); + // List all workspaces the user has been invited to. + rpc FetchInvitedWorkspaces (common.Empty) returns (WorkspacesInvitedList); + //List all workspaces the user owns. + rpc FetchOwnedWorkspaces (common.Empty) returns (WorkspacesOwnedList); // Handle a workspace invite request. rpc InviteToWorkspace (InviteRequest) returns (common.Empty); } -// A message representing a request for specific workspace. +// A message representing a request for an owned workspace. +message OwnedWorkspaceRequest { + // The workspace's name. + required string name = 1; +} + +// A message representing a request for a specific workspace. message WorkspaceRequest { - // The name of the workspace. - required string workspace = 1; + required common.Identifier id = 1; } // A message representing a list of workspaces. -message WorkspaceList { - // A vector of workspaces owned by the user. - repeated string owned = 1; +message WorkspacesInvitedList { // A vector of workspaces the user is invited to. - repeated string invited = 2; + repeated common.WorkspaceInfo invited = 1; +} + +// A message representing a list of workspaces. +message WorkspacesOwnedList { + // A vector of workspaces owned by the user. + repeated common.WorkspaceInfo owned = 1; } // A message representing an invitation to a workspace. message InviteRequest { // The user the invitation is for. required string user = 1; - // the workspace the invitation is for - required string workspace = 2; + // The workspace the invitation is for. + required common.Identifier workspace = 2; +} + +// A message representing a session event. +message SessionEvent { + // Event that occurs when you get invited to a workspace. + message InvitationEvent { + // The user that invited you. + required common.User user = 1; + // The workspace the invitation is for. + required common.WorkspaceInfo workspace = 2; + } + // Event that occurs when a user quits a workspace. + message QuitEvent { + // The user that quits. + required common.User user = 1; + // The workspace the user quit. + required common.WorkspaceInfo workspace = 2; + } + // Event that occurs when an user accepts an invite to a workspace you are in. + message AcceptEvent { + // The user that accepted the invite. + required common.User user = 1; + // The workspace the user accepted the invite for. + required common.WorkspaceInfo workspace = 2; + } + // Event that occurs when an user rejects an invite. + message RejectEvent { + // The user that rejected the invite. + required common.User user = 1; + // The workspace the invitation was for. + required common.WorkspaceInfo workspace = 2; + } + oneof event { + InvitationEvent invite = 1; + QuitEvent leave = 2; + AcceptEvent join = 3; + RejectEvent reject = 4; + } } diff --git a/proto/workspace.proto b/proto/workspace.proto index 712a3f5..33e3fd4 100644 --- a/proto/workspace.proto +++ b/proto/workspace.proto @@ -13,14 +13,18 @@ service Workspace { rpc CreateBuffer (files.BufferNode) returns (common.Empty); // Access a buffer within the workspace and returns a buffer token for it. rpc AccessBuffer (files.BufferNode) returns (common.Token); + // Transforms an ephemeral buffer in a persistent one. + rpc PinBuffer (files.BufferRequest) returns (common.Empty); // Delete a buffer. - rpc DeleteBuffer (files.BufferNode) returns (common.Empty); - // List buffers in the workspace. - rpc ListBuffers (common.Empty) returns (files.BufferTree); + rpc DeleteBuffer (files.BufferRequest) returns (common.Empty); + // List buffers in the workspace that are children of the given path. + rpc ListBuffers (files.BufferRequest) returns (files.BufferTree); // List users in the workspace. rpc ListUsers (common.Empty) returns (UserList); // List users within a given buffer. - rpc ListBufferUsers (files.BufferNode) returns (UserList); + rpc ListBufferUsers (files.BufferRequest) returns (UserList); + // Revokes all invites and kicks all active users. + rpc KickAll (common.Empty) returns (common.Empty); } // A message representing a list of users. @@ -45,6 +49,8 @@ message WorkspaceEvent { message FileCreate { // The path of the created file. required string path = 1; + // Whether the buffer is ephemeral. + required bool ephemeral = 2; } // Event that occurs when a file is renamed in a workspace. message FileRename { diff --git a/src/lib.rs b/src/lib.rs index 51a7040..2a6a51d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,33 +10,33 @@ pub mod common { tonic::include_proto!("common"); - impl From for Identity { + impl From for Identifier { fn from(id: uuid::Uuid) -> Self { let (hi, lo) = id.as_u64_pair(); - Identity { hi, lo } + Identifier { hi, lo } } } - impl From<&uuid::Uuid> for Identity { + impl From<&uuid::Uuid> for Identifier { fn from(id: &uuid::Uuid) -> Self { let (hi, lo) = id.as_u64_pair(); - Identity { hi, lo } + Identifier { hi, lo } } } - impl From for uuid::Uuid { - fn from(value: Identity) -> Self { + impl From for uuid::Uuid { + fn from(value: Identifier) -> Self { uuid::Uuid::from_u64_pair(value.hi, value.lo) } } - impl From<&Identity> for uuid::Uuid { - fn from(value: &Identity) -> Self { + impl From<&Identifier> for uuid::Uuid { + fn from(value: &Identifier) -> Self { uuid::Uuid::from_u64_pair(value.hi, value.lo) } } - impl Identity { + impl Identifier { pub fn uuid(&self) -> uuid::Uuid { uuid::Uuid::from(self) } @@ -46,26 +46,6 @@ pub mod common { /// filetree related types pub mod files { tonic::include_proto!("files"); - - impl From for BufferNode { - fn from(value: String) -> Self { - BufferNode { path: value } - } - } - - impl From<&str> for BufferNode { - fn from(value: &str) -> Self { - BufferNode { - path: value.to_string(), - } - } - } - - impl From for String { - fn from(value: BufferNode) -> Self { - value.path - } - } } /// buffer synchronisation protocol types and procedures