Making a class to handle server and client of a gun

Hello,

I am trying to make a revolver class (revolver is the only gun in the game) but I am trying to make the class handle both server and client.

I want to change this:
Screen Shot 2023-09-17 at 1.19.03 AM
To this:
Screen Shot 2023-09-17 at 1.20.01 AM

And it should be handled by this class:
Screen Shot 2023-09-17 at 1.22.39 AM

How would I do this???

Update: I tried something and it failed miserably.

I tried to have two modules handle server and client inside of revolver class…

Problem with that is cyclic dependency…

Screen Shot 2023-09-18 at 5.22.46 PM

--!strict
local Revolver = {}
Revolver.__index = Revolver

export type self = {
	_revolver: revolverTool,
	_settings: ModuleScript,
	_player: Player,
};

export type revolverTool = Tool & {
	Animations: Folder & {[string]:Animation},
	Settings: ModuleScript,
	Handle: BasePart & {[string]: Sound},
} 

export type Revolver = typeof(
	setmetatable({} :: self, Revolver)
)

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

if RunService:IsClient() then
	error("REQUIRE INSIDE OF A SERVER SCRIPT!")
end

local Source = ReplicatedStorage.Source

local Server = require(script.Cyclic.Server)

function Revolver.new(Tool: revolverTool, Player: Player): Revolver
	local self = setmetatable({}:: self, Revolver)
	
	self._revolver = Tool
	self._settings = Tool.Settings
	self._player = Player
	
	Server.new(self._revolver, self._settings) -- should automatically require Client as well from remote...
	
	return self
end

return Revolver

--!strict
local Client = {}

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Source = ReplicatedStorage.Source

local Revolver = require(script.Parent)
local Network = require(Source.Libraries.Network).Server("Client")


type self = {
	_revolver: Revolver.revolverTool,
	_settings: ModuleScript,
	_player: Player
};


export type Client = typeof(
	setmetatable({} :: self, Client)
)

function Client.new(Tool: Revolver.revolverTool, Settings: ModuleScript, Player: Player): Client
	local self = setmetatable({}:: self, Client)

	self._revolver = Tool
	self._settings = Settings
	self._player = Player

	Client:Init() -- automatically init
	return self
end

function Client:Init()
	print("Revolver Client: ON")
end

Network:On("rev_client",function(Player, Tool, Settings)
	Client.new(Tool,Settings, Player) 
end)

return Client


local Server = {}

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Source = ReplicatedStorage.Source

local Revolver = require(script.Parent)
local Client = require(script.Parent.Client)

local Network = require(Source.Libraries.Network).Server("Server")

type self = {
	_revolver: Revolver.revolverTool,
	_settings: ModuleScript,
	_player: Player,
};


export type Server = typeof(
	setmetatable({} :: self, Server)
)

function Server.new(Tool: Revolver.revolverTool, Settings: ModuleScript, Player: Player): Server
	local self = setmetatable({}:: self, Server)

	self._revolver = Tool
	self._settings = Settings
	self._player = Player
	
	Server:Init()
	
	return self
end

function Server:Init()
	Network:Fire(self._player, "rev_client",
		self._revolver,
		self._settings
	);
	
	print("Revolver Server: ON")
end

return Server