import "github.com/sceredi/co-type/broker/cmd/app"
Package main is the entrypoint of the broker application.
import "github.com/sceredi/co-type/broker/internal/config"
Package config is responsible for setting up the configuration for the broker application.
func CreateDiscoveryListener(addr string, lis net.Listener) error
CreateDiscoveryListener creates and starts the gRPC server for the discovery service. It listens on the port specified in the environment variable “BROKER_PORT” and registers the DiscoveryServiceServer with the gRPC server.
import "github.com/sceredi/co-type/broker/internal/domain"
Package domain defines the core domain entities and errors for the broker application.
var (
// ErrServerNotFound is returned when a server is not found.
ErrServerNotFound = errors.New("server not found")
// ErrServerAlreadyExists is returned when a server already exists.
ErrServerAlreadyExists = errors.New("server already exists")
// ErrServerNameInvalid is returned when a server name is invalid.
ErrServerNameInvalid = errors.New("server name is invalid")
// ErrServerAddrInvalid is returned when a server address is invalid.
ErrServerAddrInvalid = errors.New("server address is invalid")
)
Server represents a server in the broker application.
type Server struct {
Name string
Addr string
Port int32
}
func NewServer(name, addr string, port int32) (*Server, error)
NewServer creates a new Server instance with the given address.
import "github.com/sceredi/co-type/broker/internal/grpc"
Package grpc implements the gRPC server for the broker service. It provides the necessary handlers and mappers to handle gRPC requests and responses, allowing clients to interact with the broker service using gRPC protocol.
ControlHandler implements the ControlServiceServer interface and handles incoming gRPC requests for server management.
type ControlHandler struct {
control.UnimplementedControlServiceServer
// contains filtered or unexported fields
}
func NewControlHandler(serverSvc service.ServerService) *ControlHandler
NewControlHandler creates a new instance of ControlHandler with the provided ServerService.
func (h *ControlHandler) Manage(stream control.ControlService_ManageServer) error
Manage handles incoming gRPC streams for server management. It listens for messages from the stream and processes them accordingly.
import "github.com/sceredi/co-type/broker/internal/repository"
Package repository defines the interfaces for the repositories used in the application. It provides an abstraction layer for data access, allowing for different implementations without affecting the business logic.
ServerRepository defines the interface for managing servers in the broker.
type ServerRepository interface {
// Create adds a new server to the repository. It returns the created server or an error if the operation fails.
Create(server *domain.Server) (*domain.Server, error)
}
import "github.com/sceredi/co-type/broker/internal/service"
Package service contains the service layer of the broker service. The service layer is responsible for implementing the business logic of the broker service. It defines the interfaces that the handlers will use to interact with the domain models and repositories.
ServerService defines the interface for managing servers in the broker service.
type ServerService interface {
// Create creates a new server in the broker service. It takes a CreateServerRequest and returns the created Server or an error if the operation fails.
Create(name, addr string, port int32) (*domain.Server, error)
}
func NewServerService(serverRepo repository.ServerRepository) ServerService
NewServerService creates a new instance of ServerService with the provided ServerRepository and returns it.
import "github.com/sceredi/co-type/broker/internal/repository/memory"
Package memory provides an in-memory implementation of the repository interfaces defined in the repository package.
func NewServerRepository() repository.ServerRepository
NewServerRepository creates a new instance of ServerRepository.
import "github.com/sceredi/co-type/client/cmd/app"
Package main is the entry point of the application.
import "github.com/sceredi/co-type/client/internal/tui"
Package tui defines the TUI model, which is the main component of the TUI. It manages the state of the TUI and the movement between pages.
Model is the main model of the TUI.
type Model struct {
// contains filtered or unexported fields
}
func New() Model
New creates a new TUI model.
func (m Model) Init() tea.Cmd
Init initializes the model.
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)
Update updates the model based on the given message and returns the updated model and any commands to execute.
func (m Model) View() tea.View
View returns the view of the model.
import "github.com/sceredi/co-type/client/internal/tui/pages"
Package pages defines some constants of the TUI pages.
const (
// Width is the width of the pages.
Width = 60
// Height is the height of the pages.
Height = 30
)
import "github.com/sceredi/co-type/client/internal/tui/styles"
Package styles defines the styles for the TUI components.
var (
// ButtonDefault is a style for buttons with padding, border, and bold text.
ButtonDefault = lipgloss.NewStyle().Padding(0, 3).Border(lipgloss.RoundedBorder()).Bold(true)
// ButtonPrimary is a style for primary buttons with a green border and foreground.
ButtonPrimary = ButtonDefault.BorderForeground(Green).Foreground(Green)
// ButtonDanger is a style for danger buttons with a red border and foreground.
ButtonDanger = ButtonDefault.BorderForeground(Red).Foreground(Red)
// ButtonBlue is a style for blue buttons with a blue border and foreground.
ButtonBlue = ButtonDefault.BorderForeground(Blue).Foreground(Blue)
)
var (
// Red is a color for errors and warnings.
Red = lipgloss.Color("124")
// DarkRed is a darker Red.
DarkRed = lipgloss.Color("88")
// Green is a color for success messages and highlights.
Green = lipgloss.Color("106")
// DarkGreen is a darker Green.
DarkGreen = lipgloss.Color("100")
// Yellow is a color for highlights and accents.
Yellow = lipgloss.Color("172")
// Blue is a color for highlights and accents.
Blue = lipgloss.Color("66")
// Purple is a color for highlights and accents.
Purple = lipgloss.Color("132")
// Acqua is a color for highlights and accents.
Acqua = lipgloss.Color("72")
// Gray is a color for secondary text and accents.
Gray = lipgloss.Color("245")
)
var (
// PaddingAll is a style with padding of 1 on all sides.
PaddingAll = lipgloss.NewStyle().Padding(1)
// PaddingVertical is a style with padding of 1 on the top and bottom.
PaddingVertical = lipgloss.NewStyle().Padding(1, 0)
// PaddingHorizontal is a style with padding of 1 on the left and right.
PaddingHorizontal = lipgloss.NewStyle().Padding(0, 1)
)
Container is a style for a container with padding and a border.
var Container = lipgloss.NewStyle().Padding(1).Border(lipgloss.RoundedBorder(), true)
LabelBold is a style for labels that are bold.
var LabelBold = lipgloss.NewStyle().Bold(true)
func NewContainer(content string) string
NewContainer returns the given content styled with Container.
func NewLabelBold(content string) string
NewLabelBold returns the given content styled with LabelBold.
import "github.com/sceredi/co-type/client/internal/tui/pages/common"
Package common contains reusable components and functions for the TUI pages.
func NewTextinput(placeholder string, value string) textinput.Model
NewTextinput creates a new text input with the given placeholder and value.
import "github.com/sceredi/co-type/client/internal/tui/pages/end"
Package end defines the end page of the TUI.
Model is the model for the end page.
type Model struct {
// contains filtered or unexported fields
}
func New(stats domain.GameStats) Model
New creates a new and page model.
func (m Model) Init() tea.Cmd
Init initializes the end page model.
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd)
Update updates the end page model based on the given message.
func (m Model) View() string
View renders the end page.
import "github.com/sceredi/co-type/client/internal/tui/pages/game"
Package game defines the game page of the TUI.
Model is the model for the game page.
type Model struct {
// contains filtered or unexported fields
}
func New(game domain.Game) Model
New creates a new game model.
func (m Model) Init() tea.Cmd
Init initializes the game model.
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd)
Update updates the game model based on the given message.
func (m Model) View() string
View renders the game page.
import "github.com/sceredi/co-type/client/internal/tui/pages/lobby"
Package lobby defines the lobby page of the TUI.
The Model struct represents the state of the lobby page.
type Model struct {
// contains filtered or unexported fields
}
func New(player *domain.Player, lobby *domain.Lobby) Model
New creates a new lobby model for the given player and lobby.
func (m Model) Init() tea.Cmd
Init initializes the model. In this case, it does nothing and returns nil.
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd)
Update updates the model based on the given message and returns the updated model and any commands to execute.
func (m Model) View() string
View renders the lobby page as a string.
import "github.com/sceredi/co-type/client/internal/tui/pages/welcome"
Package welcome defines the welcome page of the TUI.
Model is the model for the welcome page.
type Model struct {
// contains filtered or unexported fields
}
func New() Model
New creates a new welcome model.
func (m Model) Init() tea.Cmd
Init initializes the welcome model.
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd)
Update updates the welcome model based on the given message.
func (m Model) View() string
View renders the welcome page.
import "github.com/sceredi/co-type/client/internal/tui/pages/game/messages"
Package game_messages defines the messages for the game page.
func NewGameEndCmd(stats domain.GameStats) tea.Cmd
NewGameEndCmd returns a command that creates a GameEndMsg.
GameEndMsg is a message that indicates that a game has ended.
type GameEndMsg struct {
Stats domain.GameStats
}
import "github.com/sceredi/co-type/client/internal/tui/pages/lobby/messages"
Package lobby_messages defines the messages for the lobby page.
func NewCloseSettingsCmd() tea.Cmd
NewCloseSettingsCmd returns a command that creates a CloseSettingsMsg.
func NewLeaveCmd() tea.Cmd
NewLeaveCmd returns a command that creates a LeaveMessage.
func NewPlayerReadyCmd(name string, isReady bool) tea.Cmd
NewPlayerReadyCmd returns a command that creates a PlayerReadyMsg with the given name and ready status.
func NewStartGameCmd(game domain.Game) tea.Cmd
NewStartGameCmd return a command that creates a StartGameMsg.
func NewUpdatePlayerCmd(player *domain.Player, allowedCharacters, blockedCharacters string, backspaceAllowed bool) tea.Cmd
NewUpdatePlayerCmd returns a command that creates an UpdatePlayerMsg with the given player and settings.
CloseSettingsMsg is a message that indicates that the settings modal should be closed.
type CloseSettingsMsg struct{}
LeaveMsg is a message that indicates the player wants to leave the lobby and return to the main menu.
type LeaveMsg struct{}
PlayerReadyMsg is a message that indicates that a player has changed their ready status.
type PlayerReadyMsg struct {
Name string
IsReady bool
}
StartGameMsg is a message that indicates that a game should be started.
type StartGameMsg struct {
Game domain.Game
}
UpdatePlayerMsg is a message that indicates that a player’s settings have been updated.
type UpdatePlayerMsg struct {
Player *domain.Player
AllowedCharacters string
BlockedCharacters string
BackspaceAllowed bool
}
import "github.com/sceredi/co-type/client/internal/tui/pages/welcome/messages"
Package welcome_messages defines the messages for the welcome page of the TUI.
func NewCreateLobbyCmd(lobbyCode string, playerName string) tea.Cmd
NewCreateLobbyCmd creates a new command to create a lobby.
func NewJoinLobbyCmd(lobbyCode string, playerName string) tea.Cmd
NewJoinLobbyCmd creates a new command to join a lobby with the given ID.
func NewLeaveJoinLobbyCmd() tea.Cmd
NewLeaveJoinLobbyCmd creates a new command to leave the join lobby page and go back to the welcome page.
JoinLobbyErrorMsg is a message that is sent when there is an error joining a lobby.
type JoinLobbyErrorMsg struct {
Error string
}
JoinLobbyMsg is a message that is sent when the user wants to join a lobby. It contains the ID of the lobby to join.
type JoinLobbyMsg struct {
Lobby domain.Lobby
}
LeaveJoinLobbyMsg is a message that is sent when the user wants to leave the join lobby page and go back to the welcome page.
type LeaveJoinLobbyMsg struct{}
import "github.com/sceredi/co-type/client/internal/tui/pages/lobby/components/header"
Package header defines the header component of the lobby page.
func Render(player *domain.Player, lobby *domain.Lobby) string
Render renders the header component for the given player and lobby.
import "github.com/sceredi/co-type/client/internal/tui/pages/lobby/components/playerinfo"
Package playerinfo defines the component that renders the player’s information in the lobby page.
func Render(player domain.Player) string
Render renders the player information component for the given player.
import "github.com/sceredi/co-type/client/internal/tui/pages/lobby/components/playerlist"
Package playerlist defines the player list component of the lobby page.
func Render(selectedPlayer int, lobby *domain.Lobby) string
Render renders the player list component for the given selected player and lobby.
import "github.com/sceredi/co-type/client/internal/tui/pages/lobby/components/settings"
Package settings provides a bubbletea component to edit player settings
Model is the bubbletea model for the settings component.
type Model struct {
PlayerName string
// contains filtered or unexported fields
}
func New(player *domain.Player) Model
New creates a new settings model for the given player.
func (m Model) Init() tea.Cmd
Init initializes the model. It starts the blinking cursor for the text inputs.
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd)
Update updates the model based on the given message.
func (m Model) View() string
View renders the settings editor.
import "github.com/sceredi/co-type/common/config"
Package config contains useful configuration utilities.
func Setup()
Setup initializes the configuration.
import "github.com/sceredi/co-type/common/domain"
Package domain contains the domain models for the co-type game.
Game represents the ongoing game, including the lobby and the current state of the game.
type Game struct {
Lobby Lobby
State GameState
}
GameState represents the current state of the game.
type GameState struct {
CorrectChars int
LastChar int
Status GameStatus
}
GameStats represents the statistics of a game.
type GameStats struct {
TotalTime time.Duration
Lobby Lobby
}
GameStatus represents the current status of the game.
type GameStatus int
const (
// Paused indicates that the game is currently paused.
Paused GameStatus = iota
// Running indicates that the game is currently running.
Running
// Terminated indicates that the game has been terminated.
Terminated
)
Lobby represents the state of the lobby.
type Lobby struct {
ID string
Players []*Player
Host *Player
Snippet string
}
func NewLobby(id string, host *Player) Lobby
NewLobby creates a new lobby with the given ID and host player.
func (l *Lobby) AddPlayers(players ...*Player)
AddPlayers adds the given players to the lobby.
Player represents a player in the lobby.
type Player struct {
Name string
IsReady bool
AllowedCharacters string
BlockedCharacters string
CanDelete bool
}
func NewPlayer(name string) Player
NewPlayer creates a new player with the given name and default values for other fields.
import "github.com/sceredi/co-type/common/logger"
Package logger contains logging utilities.
func Setup()
Setup sets up the default logger for cli services.
import "github.com/sceredi/co-type/common/proto/control"
const (
ControlService_Manage_FullMethodName = "/control.ControlService/Manage"
)
ControlService_ServiceDesc is the grpc.ServiceDesc for ControlService service. It’s only intended for direct use with grpc.RegisterService, and not to be introspected or modified (even as a copy)
var ControlService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "control.ControlService",
HandlerType: (*ControlServiceServer)(nil),
Methods: []grpc.MethodDesc{},
Streams: []grpc.StreamDesc{
{
StreamName: "Manage",
Handler: _ControlService_Manage_Handler,
ServerStreams: true,
ClientStreams: true,
},
},
Metadata: "common/proto/control/control.proto",
}
var File_common_proto_control_control_proto protoreflect.FileDescriptor
func RegisterControlServiceServer(s grpc.ServiceRegistrar, srv ControlServiceServer)
Envelopes for communication from the broker to servers.
type BrokerEnvelope struct {
// Types that are valid to be assigned to Payload:
//
// *BrokerEnvelope_RegisterAck
// *BrokerEnvelope_Heartbeat
Payload isBrokerEnvelope_Payload `protobuf_oneof:"payload"`
// contains filtered or unexported fields
}
func (*BrokerEnvelope) Descriptor() ([]byte, []int)
Deprecated: Use BrokerEnvelope.ProtoReflect.Descriptor instead.
func (x *BrokerEnvelope) GetHeartbeat() *Heartbeat
func (x *BrokerEnvelope) GetPayload() isBrokerEnvelope_Payload
func (x *BrokerEnvelope) GetRegisterAck() *RegisterServerAck
func (*BrokerEnvelope) ProtoMessage()
func (x *BrokerEnvelope) ProtoReflect() protoreflect.Message
func (x *BrokerEnvelope) Reset()
func (x *BrokerEnvelope) String() string
type BrokerEnvelope_Heartbeat struct {
Heartbeat *Heartbeat `protobuf:"bytes,2,opt,name=heartbeat,proto3,oneof"`
}
type BrokerEnvelope_RegisterAck struct {
RegisterAck *RegisterServerAck `protobuf:"bytes,1,opt,name=register_ack,json=registerAck,proto3,oneof"`
}
ControlServiceClient is the client API for ControlService service.
For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
The control service definition.
type ControlServiceClient interface {
// Bidirectional streaming RPC for managing servers.
Manage(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[ServerEnvelope, BrokerEnvelope], error)
}
func NewControlServiceClient(cc grpc.ClientConnInterface) ControlServiceClient
ControlServiceServer is the server API for ControlService service. All implementations must embed UnimplementedControlServiceServer for forward compatibility.
The control service definition.
type ControlServiceServer interface {
// Bidirectional streaming RPC for managing servers.
Manage(grpc.BidiStreamingServer[ServerEnvelope, BrokerEnvelope]) error
// contains filtered or unexported methods
}
This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type ControlService_ManageClient = grpc.BidiStreamingClient[ServerEnvelope, BrokerEnvelope]
This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type ControlService_ManageServer = grpc.BidiStreamingServer[ServerEnvelope, BrokerEnvelope]
Messages for heartbeat to monitor server health.
type Heartbeat struct {
// contains filtered or unexported fields
}
func (*Heartbeat) Descriptor() ([]byte, []int)
Deprecated: Use Heartbeat.ProtoReflect.Descriptor instead.
func (*Heartbeat) ProtoMessage()
func (x *Heartbeat) ProtoReflect() protoreflect.Message
func (x *Heartbeat) Reset()
func (x *Heartbeat) String() string
Acknowledgment for heartbeat.
type HeartbeatAck struct {
// contains filtered or unexported fields
}
func (*HeartbeatAck) Descriptor() ([]byte, []int)
Deprecated: Use HeartbeatAck.ProtoReflect.Descriptor instead.
func (*HeartbeatAck) ProtoMessage()
func (x *HeartbeatAck) ProtoReflect() protoreflect.Message
func (x *HeartbeatAck) Reset()
func (x *HeartbeatAck) String() string
Messages for server registration.
type RegisterServer struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Host string `protobuf:"bytes,2,opt,name=host,proto3" json:"host,omitempty"`
Port int32 `protobuf:"varint,3,opt,name=port,proto3" json:"port,omitempty"`
// contains filtered or unexported fields
}
func (*RegisterServer) Descriptor() ([]byte, []int)
Deprecated: Use RegisterServer.ProtoReflect.Descriptor instead.
func (x *RegisterServer) GetHost() string
func (x *RegisterServer) GetName() string
func (x *RegisterServer) GetPort() int32
func (*RegisterServer) ProtoMessage()
func (x *RegisterServer) ProtoReflect() protoreflect.Message
func (x *RegisterServer) Reset()
func (x *RegisterServer) String() string
Acknowledgment for server registration.
type RegisterServerAck struct {
Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"`
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
// contains filtered or unexported fields
}
func (*RegisterServerAck) Descriptor() ([]byte, []int)
Deprecated: Use RegisterServerAck.ProtoReflect.Descriptor instead.
func (x *RegisterServerAck) GetMessage() string
func (x *RegisterServerAck) GetSuccess() bool
func (*RegisterServerAck) ProtoMessage()
func (x *RegisterServerAck) ProtoReflect() protoreflect.Message
func (x *RegisterServerAck) Reset()
func (x *RegisterServerAck) String() string
Envelopes for communication between servers and the broker.
type ServerEnvelope struct {
// Types that are valid to be assigned to Payload:
//
// *ServerEnvelope_Register
// *ServerEnvelope_HeartbeatAck
Payload isServerEnvelope_Payload `protobuf_oneof:"payload"`
// contains filtered or unexported fields
}
func (*ServerEnvelope) Descriptor() ([]byte, []int)
Deprecated: Use ServerEnvelope.ProtoReflect.Descriptor instead.
func (x *ServerEnvelope) GetHeartbeatAck() *HeartbeatAck
func (x *ServerEnvelope) GetPayload() isServerEnvelope_Payload
func (x *ServerEnvelope) GetRegister() *RegisterServer
func (*ServerEnvelope) ProtoMessage()
func (x *ServerEnvelope) ProtoReflect() protoreflect.Message
func (x *ServerEnvelope) Reset()
func (x *ServerEnvelope) String() string
type ServerEnvelope_HeartbeatAck struct {
HeartbeatAck *HeartbeatAck `protobuf:"bytes,2,opt,name=heartbeat_ack,json=heartbeatAck,proto3,oneof"`
}
type ServerEnvelope_Register struct {
Register *RegisterServer `protobuf:"bytes,1,opt,name=register,proto3,oneof"`
}
UnimplementedControlServiceServer must be embedded to have forward compatible implementations.
NOTE: this should be embedded by value instead of pointer to avoid a nil pointer dereference when methods are called.
type UnimplementedControlServiceServer struct{}
func (UnimplementedControlServiceServer) Manage(grpc.BidiStreamingServer[ServerEnvelope, BrokerEnvelope]) error
UnsafeControlServiceServer may be embedded to opt out of forward compatibility for this service. Use of this interface is not recommended, as added methods to ControlServiceServer will result in compilation errors.
type UnsafeControlServiceServer interface {
// contains filtered or unexported methods
}
import "github.com/sceredi/co-type/server/cmd/app"
Package main is the entry point of the server application.
import "github.com/sceredi/co-type/server/internal/config"
Package config is responsible for setting up the configuration for the server application.
func CreateDiscoveryService(conn *grpc.ClientConn) service.DiscoveryService
CreateDiscoveryService creates a new instance of DiscoveryService using the provided gRPC connection.
import "github.com/sceredi/co-type/server/internal/grpc"
Package grpc provides the gRPC implementation of the ControlGateway interface for the server service.
ControlGateway defines the interface for managing control operations in the server service.
type ControlGateway interface {
// Register registers the server with the control service using the provided name, host, and port.
Register(name, host string, port int32) error
}
func NewControlGateway(stream grpc.BidiStreamingClient[control.ServerEnvelope, control.BrokerEnvelope]) ControlGateway
NewControlGateway creates a new instance of ControlGateway with the provided gRPC stream and returns it.
import "github.com/sceredi/co-type/server/internal/service"
Package service contains the service layer of the server service. The service layer is responsible for implementing the business logic of the server service. It defines the interfaces that the handlers will use to interact with the domain models and repositories.
DiscoveryService defines the interface for managing service discovery in the server service. It provides a method to register the server with the service discovery mechanism. The Register method is responsible for registering the server and returns an error if the operation fails.
type DiscoveryService interface {
// Register registers the server with the service discovery mechanism using the provided host and port.
Register(name, host string, port int32) error
}
func NewDiscoveryService(gtw grpc.ControlGateway) DiscoveryService
NewDiscoveryService creates a new instance of DiscoveryService with the provided ControlGateway and returns it.
Generated by gomarkdoc