git.iko.soy/lynxjs-elm/compiler
on master help sign in
Improve DX: add fork suggestions, clean command, and better dev feedback

- Suggest lynxjs-elm forks when user installs elm/browser, elm/http, or elm/virtual-dom - Add `lynxjs-elm clean` command to clear elm-stuff/ and bundler cache - Show "Watching for changes..." in dev mode so users know watcher is active - Print fallback message if QR code generation fails instead of silently failing

commit9c9b074e1f4435da0d69f2924612b8191bfa0f0d authoriko <mail@iko.soy> dateFri 20 Mar 2026, 03:44 (6 months ago) parent94127db
7 files changed+117−12
builder/src/Lynx/Patches.hs+17 builder/src/Reporting/Exit.hs+14 lynxjs-elm.cabal+1 terminal/src/Clean.hs+38 terminal/src/Dev.hs+5−1 terminal/src/Install.hs+17−11 terminal/src/Main.hs+25
builder/src/Lynx/Patches.hs+17
@@ -3,6 +3,7 @@ module Lynx.Patches
33 ( installFork
44 , installAllForks
55 , isFork
6+ , forkSuggestion
67 , injectRegistry
78 , forkContentHash
89 )
@@ -98,6 +99,22 @@ isFork pkg =
9899 pkg == Pkg.virtualDom || pkg == Pkg.browser || pkg == Pkg.http || pkg == Pkg.ui || pkg == Pkg.crypto
99100
100101
102+-- FORK SUGGESTION
103+--
104+-- When a user tries to install elm/browser, elm/virtual-dom, or elm/http,
105+-- suggest the lynxjs-elm fork instead.
106+
107+
108+forkSuggestion :: Pkg.Name -> Maybe Pkg.Name
109+forkSuggestion pkg
110+ | chars == "elm/virtual-dom" = Just Pkg.virtualDom
111+ | chars == "elm/browser" = Just Pkg.browser
112+ | chars == "elm/http" = Just Pkg.http
113+ | otherwise = Nothing
114+ where
115+ chars = Pkg.toChars pkg
116+
117+
101118
102119-- INSTALL ALL FORKS
103120--
builder/src/Reporting/Exit.hs+14
@@ -746,6 +746,7 @@ data Install
746746 | InstallHadSolverTrouble Solver
747747 | InstallUnknownPackageOnline Pkg.Name [Pkg.Name]
748748 | InstallUnknownPackageOffline Pkg.Name [Pkg.Name]
749+ | InstallForkSuggestion Pkg.Name Pkg.Name
749750 | InstallBadDetails Details
750751
751752
@@ -890,6 +891,19 @@ installToReport exit =
890891 , D.reflow $ "Maybe you want one of these instead?"
891892 ]
892893
894+ InstallForkSuggestion pkg forkPkg ->
895+ Help.docReport "FORKED PACKAGE" Nothing
896+ (
897+ D.fillSep
898+ ["The","package",D.red (D.fromPackage pkg),"has","been","replaced"
899+ ,"by",D.green (D.fromPackage forkPkg),"for","LynxJS."
900+ ]
901+ )
902+ [ D.reflow "Try this instead:"
903+ , D.indent 4 $ D.green $ D.fromChars $
904+ "lynxjs-elm install " ++ Pkg.toChars forkPkg
905+ ]
906+
893907 InstallBadDetails details ->
894908 toDetailsReport details
895909
lynxjs-elm.cabal+1
@@ -53,6 +53,7 @@ Executable lynxjs-elm
5353
5454 other-modules:
5555 Bump
56+ Clean
5657 Dev
5758 Develop
5859 Diff
terminal/src/Clean.hsnew file+38
@@ -0,0 +1,38 @@
1+module Clean
2+ ( run
3+ )
4+ where
5+
6+
7+import Control.Monad (when)
8+import qualified System.Directory as Dir
9+
10+import qualified Stuff
11+
12+
13+
14+-- RUN
15+
16+
17+run :: () -> () -> IO ()
18+run () () =
19+ do maybeRoot <- Stuff.findRoot
20+ case maybeRoot of
21+ Nothing ->
22+ putStrLn "I cannot find an elm.json file. There is nothing to clean here."
23+
24+ Just root ->
25+ do let elmStuff = root ++ "/elm-stuff"
26+ exists <- Dir.doesDirectoryExist elmStuff
27+ when exists $
28+ do Dir.removeDirectoryRecursive elmStuff
29+ putStrLn "Removed elm-stuff/"
30+ home <- Stuff.getElmHome
31+ let bundlerDir = home ++ "/bundler"
32+ bundlerExists <- Dir.doesDirectoryExist bundlerDir
33+ when bundlerExists $
34+ do Dir.removeDirectoryRecursive bundlerDir
35+ putStrLn "Removed bundler cache."
36+ if exists || bundlerExists
37+ then putStrLn "All clean!"
38+ else putStrLn "Already clean — nothing to remove."
terminal/src/Dev.hs+5−1
@@ -114,6 +114,8 @@ run path (Flags maybePort verbose) =
114114 putStrLn ""
115115
116116 -- Watch for changes, recompile, and rebuild
117+ putStrLn " Watching for changes..."
118+ putStrLn ""
117119 let cleanup = do Process.terminateProcess serveHandle
118120 _ <- Process.waitForProcess serveHandle
119121 return ()
@@ -296,7 +298,9 @@ printQrCode bundlerDir url =
296298 exitCode <- Process.waitForProcess ph
297299 case exitCode of
298300 SysExit.ExitSuccess -> return ()
299− SysExit.ExitFailure _ -> return () -- silently skip if not available
301+ SysExit.ExitFailure _ ->
302+ do putStrLn " Scan the URL above in LynxJS Explorer to preview."
303+ putStrLn ""
300304
301305
302306
terminal/src/Install.hs+17−11
@@ -18,6 +18,7 @@ import qualified Elm.Details as Details
1818import qualified Elm.Package as Pkg
1919import qualified Elm.Outline as Outline
2020import qualified Elm.Version as V
21+import qualified Lynx.Patches as Patches
2122import qualified Reporting
2223import Reporting.Doc ((<+>))
2324import qualified Reporting.Doc as D
@@ -50,17 +51,22 @@ run args () =
5051 return (Left (Exit.InstallNoArgs elmHome))
5152
5253 Install pkg ->
53− Task.run $
54− do env <- Task.eio Exit.InstallBadRegistry $ Solver.initEnv
55− oldOutline <- Task.eio Exit.InstallBadOutline $ Outline.read root
56− case oldOutline of
57− Outline.App outline ->
58− do changes <- makeAppPlan env pkg outline
59− attemptChanges root env oldOutline V.toChars changes
60−
61− Outline.Pkg outline ->
62− do changes <- makePkgPlan env pkg outline
63− attemptChanges root env oldOutline C.toChars changes
54+ case Patches.forkSuggestion pkg of
55+ Just forkPkg ->
56+ return (Left (Exit.InstallForkSuggestion pkg forkPkg))
57+
58+ Nothing ->
59+ Task.run $
60+ do env <- Task.eio Exit.InstallBadRegistry $ Solver.initEnv
61+ oldOutline <- Task.eio Exit.InstallBadOutline $ Outline.read root
62+ case oldOutline of
63+ Outline.App outline ->
64+ do changes <- makeAppPlan env pkg outline
65+ attemptChanges root env oldOutline V.toChars changes
66+
67+ Outline.Pkg outline ->
68+ do changes <- makePkgPlan env pkg outline
69+ attemptChanges root env oldOutline C.toChars changes
6470
6571
6672
terminal/src/Main.hs+25
@@ -15,6 +15,7 @@ import Terminal
1515import Terminal.Helpers
1616
1717import qualified Bump
18+import qualified Clean
1819import qualified Dev
1920import qualified Develop
2021import qualified Diff
@@ -40,6 +41,7 @@ main =
4041 , make
4142 , install
4243 , uninstall
44+ , clean
4345 , bump
4446 , diff
4547 , publish
@@ -288,6 +290,29 @@ uninstall =
288290
289291
290292
293+-- CLEAN
294+
295+
296+clean :: Terminal.Command
297+clean =
298+ let
299+ summary =
300+ "Remove cached build artifacts. This clears elm-stuff/ in the current\
301+ \ project and the shared bundler cache."
302+
303+ details =
304+ "The `clean` command removes cached build artifacts:"
305+
306+ example =
307+ reflow
308+ "This is useful when you hit strange build errors or want a fresh start.\
309+ \ It removes elm-stuff/ from your project and the bundler cache. Your\
310+ \ source code and elm.json are not touched."
311+ in
312+ Terminal.Command "clean" (Common summary) details example noArgs noFlags Clean.run
313+
314+
315+
291316-- PUBLISH
292317
293318