Throughout this week, we've published a series of articles contributed by some well-known people within the F# community focused on web and cloud programming. Today, we're announcing the launch of the SAFE stack initiative, which brings all of the elements together as a cohesive story:
- `Saturn` model for server-side web programming
- `Azure` for cloud-based systems
- `Fable` for Javascript-enabled applications
- `Elmish` for an easy-to-understand UI programming model
- Modern programming model
- Saturn combines the well known MVC pattern with the power of FP and F# to make web programming fun and easy.
- High performance
- Saturn builds on top of highly optimized, and battle tested technologies such as ASP.NET Core, Giraffe and Kestrel.
- Developer experience
- Saturn provides set of tools, templates and guides that makes creating and maintaining applications seamlessly.
- Created by Community
- Saturn is created and maintained by well known members of the F# OSS Community and supported by industrial users.
run Run Building project with version: LocalBuild Shortened DependencyGraph for Target Run: <== Run <== InstallClient <== Clean
The running order is: Group - 1 - Clean Group - 2 - InstallClient Group - 3 - Run Starting target 'Clean' /workspaces/fsharp-practice/src/Client> "dotnet" fable clean --yes (In: false, Out: false, Err: false) Fable 4.1.4: F# to JavaScript compiler Minimum fable-library version (when installed from npm): 1.1.1
Thanks to the contributor! @zaaack Stand with Ukraine! https://standwithukraine.com.ua/
This will recursively delete all *.fs.js[.map] files in /workspaces/fsharp-practice/src/Client No files have been deleted. If Fable output is in another directory, pass it as argument. Finished (Success) 'Clean' in 00:00:00.4986175 Starting target 'InstallClient' .> "/usr/local/share/nvm/versions/node/v20.10.0/bin/npm" install (In: false, Out: false, Err: false) npm WARN deprecated querystring@0.2.1: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. npm WARN deprecated uuid@3.2.1: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.
added 171 packages, and audited 172 packages in 15s
21 packages are looking for funding run `npm fund` for details
3 moderate severity vulnerabilities
To address all issues (including breaking changes), run: npm audit fix --force
Run `npm audit` for details. npm notice npm notice New patch version of npm available! 10.2.3 -> 10.2.5 npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.2.5 npm notice Run npm install -g npm@10.2.5 to update! npm notice Finished (Success) 'InstallClient' in 00:00:15.7005897 Starting target 'Run' /workspaces/fsharp-practice/src/Shared> "dotnet" build (In: false, Out: false, Err: false) MSBuild version 17.8.3+195e7f5a3 for .NET Determining projects to restore... Restored /workspaces/fsharp-practice/src/Shared/Shared.fsproj (in 163 ms). Shared -> /workspaces/fsharp-practice/src/Shared/bin/Debug/net8.0/Shared.dll
Build succeeded. 0 Warning(s) 0 Error(s)
Time Elapsed 00:00:03.69 server: /workspaces/fsharp-practice/src/Server> dotnet watch run client: /workspaces/fsharp-practice/src/Client> dotnet fable watch -o output -s --run npx vite /workspaces/fsharp-practice/src/Server> "dotnet" watch run (In: false, Out: true, Err: true)/workspaces/fsharp-practice/src/Client> "dotnet" fable watch -o output -s --run npx vite (In: false, Out: true, Err: true)
server: dotnet watch ⌚ Polling file watcher is enabled client: Fable 4.1.4: F# to JavaScript compiler client: Minimum fable-library version (when installed from npm): 1.1.1 client: Thanks to the contributor! @sasmithjr client: Stand with Ukraine! https://standwithukraine.com.ua/ client: Using polling watcher. client: Parsing Client.fsproj... client: .> dotnet restore Client.csproj -p:FABLE_COMPILER=true -p:FABLE_COMPILER_4=true -p:FABLE_COMPILER_JAVASCRIPT=true client: Determining projects to restore... client: Paket version 8.0.0+6bcb14ec191f11e984ff0e58016f5987a5cfa8f6 client: The last full restore is still up to date. Nothing left to do. client: Total time taken: 0 milliseconds server: dotnet watch 🚀 Started client: Paket version 8.0.0+6bcb14ec191f11e984ff0e58016f5987a5cfa8f6 client: Restoring /workspaces/fsharp-practice/src/Client/Client.csproj client: Starting restore process. client: Total time taken: 0 milliseconds client: Restored /workspaces/fsharp-practice/src/Client/Client.csproj (in 214 ms). client: 1 of 2 projects are up-to-date for restore. server: Unhandled exception. System.ArgumentException: An item with the same key has already been added. Key: /workspaces/fsharp-practice/src/Server/obj/Debug/net8.0/staticwebassets server: at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) server: at Microsoft.DotNet.Watcher.Internal.PollingFileWatcher.<CheckForChangedFiles>b__23_0(FileSystemInfo f) server: at Microsoft.DotNet.Watcher.Internal.PollingFileWatcher.ForeachEntityInDirectory(DirectoryInfo dirInfo, Action`1 fileAction) server: at Microsoft.DotNet.Watcher.Internal.PollingFileWatcher.ForeachEntityInDirectory(DirectoryInfo dirInfo, Action`1 fileAction) server: at Microsoft.DotNet.Watcher.Internal.PollingFileWatcher.ForeachEntityInDirectory(DirectoryInfo dirInfo, Action`1 fileAction) server: at Microsoft.DotNet.Watcher.Internal.PollingFileWatcher.ForeachEntityInDirectory(DirectoryInfo dirInfo, Action`1 fileAction) server: at Microsoft.DotNet.Watcher.Internal.PollingFileWatcher.CheckForChangedFiles() server: at Microsoft.DotNet.Watcher.Internal.PollingFileWatcher.PollingLoop() client: Some Nuget packages contain information about NPM dependencies that can be managed by Femto: https://github.com/Zaid-Ajaj/Femto client: Project and references (67 source files) parsed in 10372ms server: warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60] server: Storing keys in a directory '/home/vscode/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed. For more information go to https://aka.ms/aspnet/dataprotectionwarning server: info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[62] server: User profile is available. Using '/home/vscode/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest. server: info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[58] server: Creating key {b2652658-4977-45a5-809c-2f3f8a9cc018} with creation date 2023-12-16 16:56:54Z, activation date 2023-12-16 16:56:54Z, and expiration date 2024-03-15 16:56:54Z. server: warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35] server: No XML encryptor configured. Key {b2652658-4977-45a5-809c-2f3f8a9cc018} may be persisted to storage in unencrypted form. server: info: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[39] server: Writing data to file '/home/vscode/.aspnet/DataProtection-Keys/key-b2652658-4977-45a5-809c-2f3f8a9cc018.xml'. server: warn: Microsoft.AspNetCore.Hosting.Diagnostics[15] server: Overriding HTTP_PORTS '8080' and HTTPS_PORTS ''. Binding to values defined by URLS instead 'http://localhost:5000'. server: info: Microsoft.AspNetCore.Server.Kestrel[0] server: Unable to bind to http://localhost:5000 on the IPv6 loopback interface: 'Cannot assign requested address'. server: info: Microsoft.Hosting.Lifetime[14] server: Now listening on: http://localhost:5000 server: info: Microsoft.Hosting.Lifetime[0] server: Application started. Press Ctrl+C to shut down. server: info: Microsoft.Hosting.Lifetime[0] server: Hosting environment: Development server: info: Microsoft.Hosting.Lifetime[0] server: Content root path: /workspaces/fsharp-practice/src/Server client: Loaded Feliz.HookAttribute from ../../../../home/vscode/.nuget/packages/feliz.compilerplugins/2.2.0/lib/netstandard2.0/Feliz.CompilerPlugins.dll client: Loaded Feliz.ReactComponentAttribute from ../../../../home/vscode/.nuget/packages/feliz.compilerplugins/2.2.0/lib/netstandard2.0/Feliz.CompilerPlugins.dll client: Loaded Feliz.ReactMemoComponentAttribute from ../../../../home/vscode/.nuget/packages/feliz.compilerplugins/2.2.0/lib/netstandard2.0/Feliz.CompilerPlugins.dll client: Started Fable compilation... client: Fable compilation finished in 8173ms client: .> npx vite client: Watching .. client: VITE v5.0.5 ready in 1074 ms client: ➜ Local: http://localhost:8080/ client: ➜ Network: use --host to expose client: ➜ press h + enter to show help