simplicity
People want simple tools. It makes total sense... but how do we confirm we provide simplicity? At FUDD, we have defined a metric to benchmark our work and make sure that we deliver simplicity consistently. Our benchmark can even measure other tools so we know we are either outperforming the alternative solutions or we haven't reached our goal yet!
sppm
Security, Productivity, Performance and Maintenance: the 4 priorities of the FUDD ecosystem. Day after day we read stories about people agonising over breaches, features that are years late in deployment, application speed that frustrate users and code bases that are frozen in the past with no way to unstuck them. If AI, crypto and the methaverse are upon us, we better clean up this mess or we're definitely doomed.
ai-proof
The most understood element about AI is that it implies upskilling. How can you move upward if the tech you use is stuck at the bottom? FUDD ecosystem has plenty of expansion capacity to stay relevant in the AI-accelerated development world we're transitioning in.
WARNING: this project is very much work in progress!!
PROGRESS STATUS
Daniell > Parses Hugo, NextJS and Fuddle projects; classifies all components in a project; applies content
and theme
rules for Hugo; applies pages
and components
rules for NextJS; parse front-matter and markdown for Hugo; compiles templates in themes for Hugo; compiles TSX files; executes the template files with fake data context for Hugo; outputs the HTML for Hugo; parses the Fuddle template files for a code project; creates a new directory tree as per template; executes the template logic and generates the output files in the right location.
Easy-Wordy > PHP SAPI integration and management (based on fpm); all WordPress routes defined; PHP execution of WP files matching the routes; PHP output buffer management and HTTP reply to client; partial request parameter extraction and SAPI global variables population; misc PHP functions calling from Haskell; WordPress parameters in config file; demo WP instance installation; MySQL connectivity; Postgresql connectivity; Websocket support; Htmx support; EW test application (flowbite admin dashboard demo); WP Core code analysis (92% of files); WP code AST storage in DB; WP code browsing and visualization on EW application.
Fuddle > Elm compiler and package server fork; Template-extension definition; proof-of-concept template examples.
Cannelle > Parse Golang, compiles and run Jinja2 (using Ginger project); generic TreeSitter-to-internal AST model; parses PHP, TSX and Fuddle syntax to internal AST; VM bytecode specification done (v1); VM function call and return model implemented; VM dynamic field load/store implemented; VM stack and heap implemented; VM constant pool implemented; template storage model specified; template to disk read/write implemented; compiles Golang to VM bytecode; transforms Hugo templates to storage model; compiles Fuddle records and map/fold logic to VM bytecode; Haskell-TreeSitter fork and updates for Fuddle template syntax support.
KnowDoc > Roadmap; technology identification; knowledge base design; prototype definition.
Tutorial > Write up; demo assets and DB population; iHaskell extension; implementation as Jupyter Notebook; docker image wrapup; text-to-speech generation (openai).
HELP NEEDED
Community > Volunteer recruitment strategy; content creation on media channels (youtube, instgram, x, bluesky, discord); volunteer skillset classification; events; feedback loop; governance structure; cooperation with Haskell & Elm communities.
Coding > Fuddle compilation (type resolution, bytecode generation); package manager (configuration, chaining); KnowDoc (db population workflow, prototype UI); WP code annotation (UI); EW distributed proof-of-concept; Cannelle's automatic route extration and implicit API generation; cabal/stack package introspection (UI); dynamic library linking facilitation in Haskell runtime; EW embedded VM for Fuddle execution.
Website > visual assets; esthetic presentation; content; sandbox Fuddle execution.
Seeing is believing!
Get the ecosystem quickly on Docker, or just install the tools on your machine.
print "hello world"
import Servant
import Network.Wai.Handler.Warp (run)
import Network.HTTP.Types (status200)
run 8080 $
\_ respond -> respond $
responseLBS status200 [("Content-Type", "text/html")] $
"<h1>Hello World</h1>"
import qualified Network.HTTP.Client as N
import qualified Network.HTTP.Client.TLS as N
vehicleFetch query =
let
url = "GET https://vpic.nhtsa.dot.gov/api/vehicles/" <> query
request = N.setQueryString [("format", Just "json")] $ N.parseRequest_ url
settings = N.tlsManagerSettings
in do
reqMgr <- N.newManager settings
N.httpLbs request reqMgr
response <- vehicleFetch "getallmakes"
streamHandler :: MonadIO m => Ws.Connection -> m ()
streamHandler conn = do
liftIO $ Ws.withPingThread conn 30 (pure ()) $ do
-- if you want to inspect streaming: liftIO $ Ws.sendTextData conn ("<div id="notifications" hx-swap-oob="beforeend">Some message</div?" :: ByteString)
handleClient
where
handleClient = do
rezA <- tryAny $ forever receiveStream
case rezA of
Left err -> do
liftIO . putStrLn $ "@[streamHandler] situation: " <> show err
closeConnection
Right _ -> do
liftIO $ putStrLn "@[streamHandler] client disconnected."
pure ()
receiveStream = do
rezA <- Ws.receiveDataMessage conn
case rezA of
Ws.Text msg decodedMsg ->
let
hxMsg = eitherDecode msg :: Either String HxWsMessage
in
case hxMsg of
Left err -> do
putStrLn $ "@[receiveStream] invalid HxWsMessage: " <> (T.unpack . T.decodeUtf8 . LBS.toStrict) msg
putStrLn $ "@[receiveStream] error: " <> show err
Right hxMsg ->
Ws.sendTextData conn $ H.renderHtml $ htmxReply hxMsg.wsMessage
Ws.Binary msg ->
putStrLn "@[receiveStream] received binary."
closeConnection = do
Ws.sendClose conn ("Bye" :: ByteString)
void $ Ws.receiveDataMessage conn
htmxReply aMessage =
H.tbody H.! A.id "notifications" H.! X.hxSwapOob "beforeend" $ do
H.tr $ do
H.td H.! A.class_ "px-6 py-4 whitespace-nowrap text-sm text-slate-900" $ H.toHtml aMessage
data HxWsHeaders = HxWsHeaders {
request :: T.Text
, trigger :: T.Text
, triggerName :: Maybe T.Text
, target :: T.Text
, currentURL :: T.Text
}
deriving stock (Show, Generic)
instance FromJSON HxWsHeaders where
parseJSON (Object obj) = HxWsHeaders <$>
obj .: "HX-Request"
<*> obj .: "HX-Trigger"
<*> obj .:? "HX-Trigger-Name"
<*> obj .: "HX-Target"
<*> obj .: "HX-Current-URL"
data HxWsMessage = HxWsMessage {
wsMessage :: T.Text
, headers :: HxWsHeaders
}
deriving (Show, Generic)
instance FromJSON HxWsMessage where
parseJSON (Object obj) = HxWsMessage <$>
obj .: "ws-message"
<*> obj .: "HEADERS"
the FUDD ecosystem exists solely due to the incalculable hours of efforst supplied by those brade people who believe in open source and the taming of advanced technologies.
contributors
Explore our GitHub repositories.