Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Development Server #675

Merged
merged 3 commits into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 25 additions & 93 deletions src/reactor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ module Mint

@sockets = [] of HTTP::WebSocket

getter ast : Ast = Ast.new
getter script : String?

def self.start(host : String, port : Int32, auto_format : Bool, live_reload : Bool)
Expand All @@ -30,87 +29,42 @@ module Mint

workspace = Workspace.current
workspace.format = auto_format

init(workspace)
workspace.check_env = true
workspace.check_everything = false

workspace.on "change" do |result|
update result
notify
case result
when Ast
# Compile.
@script = Compiler.compile workspace.type_checker.artifacts, {
css_prefix: workspace.json.application.css_prefix,
web_components: workspace.json.web_components,
relative: false,
optimize: false,
build: false,
}

@artifacts = workspace.type_checker.artifacts
@error = nil
when Error
@error = result.to_html
@artifacts = nil
@script = nil
end

# Notifies all connected sockets to reload the page.
@sockets.each(&.send("reload"))
end

# Do the initial parsing and type checking.
workspace.update_cache
workspace.watch

watch_for_changes
setup_kemal

Server.run "Development", @host, @port
end

def init(workspace)
prefix = "#{COG} Parsing files"
line = ""

elapsed = Time.measure do
workspace.initialize_cache do |_, index, size|
counter =
"#{index} / #{size}".colorize.mode(:bold)

line =
"#{prefix}: #{counter}".ljust(line.size)

terminal.io.print("#{line}\r")
terminal.io.flush
end
end

elapsed = TimeFormat.auto(elapsed).colorize.mode(:bold)
terminal.io.puts "#{prefix}... #{elapsed}".ljust(line.size)

@ast = workspace.ast
compile_script
rescue error : Error
@error = error.to_html
end

def update(result)
case result
when Ast
@ast = result
@error = nil
compile_script
when Error
@error = result.to_html
end
end

def compile_script
# Fetch options from the applications
json =
MintJson.parse_current

# Create a brand new TypeChecker.
type_checker =
TypeChecker.new(ast, web_components: json.web_components.keys)

# Type check.
type_checker.check

# Compile.
@script = Compiler.compile type_checker.artifacts, {
css_prefix: json.application.css_prefix,
web_components: json.web_components,
relative: false,
optimize: false,
build: false,
}
@artifacts = type_checker.artifacts
@error = nil
rescue error : Error
@error = error.to_html
@artifacts = nil
@script = nil
end

def live_reload
if @live_reload
%(<script src="/live-reload.js"></script>)
Expand Down Expand Up @@ -231,28 +185,6 @@ module Mint
end
end

# Notifies all connected sockets to reload the page.
def notify
@sockets.each(&.send("reload"))
end

# Sets up watchers to detect changes
def watch_for_changes
Env.env.try do |file|
spawn do
Watcher.watch([file]) do
Env.load do
terminal.measure "#{COG} Environment variables changed, recompiling..." do
compile_script
end

notify
end
end
end
end
end

def terminal
Render::Terminal::STDOUT
end
Expand Down
3 changes: 2 additions & 1 deletion src/type_checker.cr
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ module Mint
] of Checkable

getter records, artifacts, formatter, web_components
getter? check_everything

property? checking = true

Expand All @@ -71,7 +72,7 @@ module Mint

@stack = [] of Ast::Node

def initialize(ast : Ast, @check_env = true, @web_components = [] of String)
def initialize(ast : Ast, @check_env = true, @web_components = [] of String, @check_everything = true)
ast.normalize

@languages = ast.unified_locales.map(&.language)
Expand Down
12 changes: 7 additions & 5 deletions src/type_checkers/top_level.cr
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ module Mint
# this will not be compiled.
self.checking = false

check_all node.components
check_all node.unified_modules
if check_everything?
check_all node.components
check_all node.unified_modules

resolve node.providers
resolve node.stores
resolve node.type_definitions
resolve node.providers
resolve node.stores
resolve node.type_definitions
end

VOID
end
Expand Down
24 changes: 22 additions & 2 deletions src/workspace.cr
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ module Mint

@event_handlers = {} of String => Array(ChangeProc)
@cache = {} of String => Ast
@env_watcher : Watcher?
@pattern = %w[]

getter type_checker : TypeChecker
Expand All @@ -57,6 +58,8 @@ module Mint
getter error : Error?
getter root : String

property? check_everything : Bool = true
property? check_env : Bool = false
property? format : Bool = false

def initialize(@root : String)
Expand All @@ -80,6 +83,11 @@ module Mint
@static_watcher =
Watcher.new(all_static_pattern)

@env_watcher =
Env.env.try do |file|
Watcher.new([file])
end

@type_checker =
TypeChecker.new(Ast.new)
end
Expand Down Expand Up @@ -160,6 +168,14 @@ module Mint
reset_cache
end
end

spawn do
@env_watcher.try &.watch do
Env.load do
update_cache
end
end
end
end

def files
Expand Down Expand Up @@ -239,8 +255,12 @@ module Mint
end

private def check!
@type_checker = Mint::TypeChecker.new(ast, check_env: false)
@type_checker.check
@type_checker =
Mint::TypeChecker.new(
check_everything: check_everything?,
check_env: check_env?,
ast: ast
).tap(&.check)
end

private def call(event, arg)
Expand Down