From 1a0600d03e8e7b60ba9bd77ac66dc67d0ee0ea75 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sun, 26 Nov 2023 22:20:58 -0600 Subject: [PATCH] added: many more pages --- onyx-pkg.kdl | 2 +- src/app.onyx | 41 ++- www/packages/core_packages.json | 87 ++++++ www/static/css/new_style.css | 35 ++- www/templates/pages/docs.html | 5 +- www/templates/pages/docs/env_setup.html | 1 + www/templates/pages/docs/getting_started.html | 5 +- .../pages/docs/guide_http_server.html | 295 ++++++++++++++++++ www/templates/pages/docs/guides.html | 39 +++ www/templates/pages/docs/install.html | 1 + www/templates/pages/docs/package.html | 194 ++++++++++++ www/templates/pages/docs/package_list.html | 82 +++++ www/templates/pages/homepage.html | 4 + 13 files changed, 783 insertions(+), 8 deletions(-) create mode 100644 www/packages/core_packages.json create mode 100644 www/templates/pages/docs/guide_http_server.html create mode 100644 www/templates/pages/docs/guides.html create mode 100644 www/templates/pages/docs/package.html create mode 100644 www/templates/pages/docs/package_list.html diff --git a/onyx-pkg.kdl b/onyx-pkg.kdl index c15c6fd..f2f4f56 100644 --- a/onyx-pkg.kdl +++ b/onyx-pkg.kdl @@ -23,7 +23,7 @@ build { source "build.onyx" } wasmer { - target "wasmer.wasm" + target "site.wasm" runtime "wasi" source "build.onyx" define "WASIX" "CGI_MODE" diff --git a/src/app.onyx b/src/app.onyx index 9180988..fad9de7 100644 --- a/src/app.onyx +++ b/src/app.onyx @@ -50,6 +50,24 @@ reg: otmp.TemplateRegistry; @route.{.GET, "/docs/getting_started"} (req: &Req, res: &Res) => res->render("pages/docs/getting_started", null); +@route.{.GET, "/docs/guides"} +(req: &Req, res: &Res) => res->render("pages/docs/guides", null); + +@route.{.GET, "/docs/guides/http-server"} +(req: &Req, res: &Res) => res->render("pages/docs/guide_http_server", null); + +@route.{.GET, "/docs/packages"} +(req: &Req, res: &Res) => res->render("pages/docs/package", null); + +@route.{.GET, "/docs/packages/list"} +(req: &Req, res: &Res) { + res->render("pages/docs/package_list", &.{ + core_packages = core_packages, + third_party_packages = third_party_packages + }); +} + + @route.{.GET, "/robots.txt"} (req: &Req, res: &Res) { res->file("./www/static/robots.txt"); @@ -99,6 +117,7 @@ news_articles: Cached_Resource([] Article); main :: () { default_log_level(.Error); + load_library_list(); reg = otmp.registry(); reg->load_directory("./www/templates", ".html"); @@ -158,7 +177,7 @@ main :: () { logger := http.server.logger(style=.V2); pipes->pipe(&logger); - app := http.server.tcp(pipes, .{ thread_count = 8 }); + app := http.server.tcp(pipes, .{ thread_count = 4 }); port := conv.parse_int(os.env("SERVER_PORT") ?? "8000"); @@ -168,3 +187,23 @@ main :: () { } +Package :: struct { + url, name, description: str; +} + +#local { + core_packages: [] Package; + third_party_packages: [] Package; +} + +load_library_list :: () { + os.get_contents("www/packages/core_packages.json") + |> json.decode_into(&core_packages); + + slice.sort(core_packages, (a, b) => string.compare(a.name, b.name)); + + os.get_contents("www/packages/third_party_packages.json") + |> json.decode_into(&third_party_packages); + + slice.sort(third_party_packages, (a, b) => string.compare(a.name, b.name)); +} diff --git a/www/packages/core_packages.json b/www/packages/core_packages.json new file mode 100644 index 0000000..545e49b --- /dev/null +++ b/www/packages/core_packages.json @@ -0,0 +1,87 @@ +[ + { + "name": "http-server", + "url": "https://github.com/onyx-lang/pkg-http-server", + "description": "" + }, + { + "name": "raylib", + "url": "https://github.com/onyx-lang/pkg-raylib", + "description": "" + }, + { + "name": "stb_image", + "url": "https://github.com/onyx-lang/pkg-stb_image", + "description": "" + }, + { + "name": "stb_truetype", + "url": "https://github.com/onyx-lang/pkg-stb_truetype", + "description": "" + }, + { + "name": "perlin", + "url": "https://github.com/onyx-lang/pkg-perlin", + "description": "" + }, + { + "name": "postgres", + "url": "https://github.com/onyx-lang/pkg-postgres", + "description": "" + }, + { + "name": "postgres-orm", + "url": "https://github.com/onyx-lang/pkg-postgres-orm", + "description": "" + }, + { + "name": "qoi", + "url": "https://github.com/onyx-lang/pkg-qoi", + "description": "" + }, + { + "name": "http-client", + "url": "https://github.com/onyx-lang/pkg-http-client", + "description": "" + }, + { + "name": "openssl", + "url": "https://github.com/onyx-lang/pkg-openssl", + "description": "" + }, + { + "name": "glfw3", + "url": "https://github.com/onyx-lang/pkg-glfw3", + "description": "" + }, + { + "name": "openal", + "url": "https://github.com/onyx-lang/pkg-openal", + "description": "" + }, + { + "name": "opengles", + "url": "https://github.com/onyx-lang/pkg-opengles", + "description": "" + }, + { + "name": "opencl", + "url": "https://github.com/onyx-lang/pkg-opencl", + "description": "" + }, + { + "name": "ncurses", + "url": "https://github.com/onyx-lang/pkg-ncurses", + "description": "" + }, + { + "name": "json-rpc", + "url": "https://github.com/onyx-lang/pkg-json-rpc", + "description": "" + }, + { + "name": "otmp", + "url": "https://github.com/onyx-lang/pkg-otmp", + "description": "" + } +] diff --git a/www/static/css/new_style.css b/www/static/css/new_style.css index 0a5223b..b46df35 100644 --- a/www/static/css/new_style.css +++ b/www/static/css/new_style.css @@ -43,7 +43,7 @@ body { a { color: var(--text); - text-decoration: none; + text-decoration: underline; } a.link-button { @@ -198,6 +198,8 @@ code { p code { border-radius: 4px; padding: 2px; + border: 1px solid var(--accent); + background: var(--accent-background); } @font-face { @@ -364,9 +366,9 @@ pre code { } main blockquote { - border-left: 4px solid var(--dark-background-color); - background-color: var(--light-background-color); - margin-top: 12px; + border-left: 4px solid var(--accent); + background-color: var(--accent-background); + margin-top: 16px; padding: 8px; } @@ -444,6 +446,31 @@ main li { padding-bottom: 32px; } +table { + border-radius: 8px; + border: 1px solid var(--accent); + width: 100%; + background: linear-gradient(135deg, #000, var(--accent-background)); + box-shadow: 0px 7px 41px 30px rgba(200, 200, 230, 0.2); + margin-top: 24px !important; +} + +table tr:nth-child(2n) { + background: var(--accent-background); + border: none; +} + +table th { + font-size: 1.1rem; + border: none; + padding: 8px; +} + +table td { + padding: 8px; + border: none; +} + .scrollport > div { min-width: 1000px; } diff --git a/www/templates/pages/docs.html b/www/templates/pages/docs.html index d41c75d..ac61874 100644 --- a/www/templates/pages/docs.html +++ b/www/templates/pages/docs.html @@ -25,9 +25,11 @@ Onyx Documentation

Learn

- Learn the core ideas behind programming in Onyx. + Learn the core ideas behind programming in Onyx, and how to use developer tooling.

+ Guides + Package Manager Language Reference

@@ -39,6 +41,7 @@ Onyx Documentation

Core packages + External packages

diff --git a/www/templates/pages/docs/env_setup.html b/www/templates/pages/docs/env_setup.html index b8221f5..09ecac0 100644 --- a/www/templates/pages/docs/env_setup.html +++ b/www/templates/pages/docs/env_setup.html @@ -6,6 +6,7 @@

Setting Up Your Environment for Onyx

+
⇦ Back to the docs

The following sections will help set up an environment for you to program Onyx effectively.

diff --git a/www/templates/pages/docs/getting_started.html b/www/templates/pages/docs/getting_started.html index 7d318e7..054c2b3 100644 --- a/www/templates/pages/docs/getting_started.html +++ b/www/templates/pages/docs/getting_started.html @@ -2,10 +2,13 @@ Getting Started {{ endblock }} +{{ let navbar_page = "docs" }} + {{ block "page_content" }}

Getting Started

+
⇦ Back to the docs
@@ -80,4 +83,4 @@ Hello, Onyx! {{ endblock }} -{{ extends "pages/normal_page" }} \ No newline at end of file +{{ extends "pages/normal_page" }} diff --git a/www/templates/pages/docs/guide_http_server.html b/www/templates/pages/docs/guide_http_server.html new file mode 100644 index 0000000..d7a8c97 --- /dev/null +++ b/www/templates/pages/docs/guide_http_server.html @@ -0,0 +1,295 @@ +{{block "title"}}HTTP Server in Onyx{{endblock}} + +{{ let navbar_page = "docs" }} + +{{ block "page_content" }} + +
+

Guide - HTTP Server

+
⇦ Back to the docs
+ +

+ This guide walks you through all steps of setting up an HTTP server Onyx, + writing some routes on it, and then deploying it to Wasmer Edge or Spin + using WCGI. +

+
+ +
+
+

Setting up the Project

+
+ +

+ First, you need create a new folder for this project, and initialize that folder as an Onyx project. + See the package manager explainer for more details. +

+ +
mkdir my-http-server
+cd my-http-server
+onyx package init
+ +

+ Then you need to add the HTTP server package to this project, and synchronize + changes to install the package. +

+
# Add the package
+onyx package add http-server
+# Synchronize changes
+onyx package sync
+ +

+ Once the package is successfully fetched, you can start writing some code! +

+
+ +
+
+

Writing the code

+
+ +

+ You can now write the code for your server. + Begin by creating a main.onyx file that will house your code. + In this file, you first need to load your packages and use http package. +

+ +
#load "./lib/packages"
+
+// Include everything from the core library.
+use core {*}
+
+// Include the http package, and specifically use some common symbols.
+use http
+use http.server { Request, Response, route }
+ +

+ Now you write a simple main function that will create a TCP HTTP server, + with one route for the getting "/" endpoint. +

+ +
main :: () {
+    // Create a router that will route the traffic.
+    router := http.server.router();
+
+    // Register a handler for 'GET /'.
+    router->get("/", (req: &Request, res: &Response) {
+        // Respond with HTML
+        res->html("

HTTP Server in Onyx!

"); + + // Set status to 200 + res->status(200); + + // Mark the response as completed + res->end(); + }); + + + // Create a TCP server out of your router. + app := http.server.tcp(&router); + + // Serve on port 8000. + app->serve(8000); +}
+ +

+ That is everything you need to create a simple HTTP server that will respond to a GET + request on / with "<h1>HTTP Server in Onyx!<h1>". +

+ +

+ You could define more routes in this way, using router->get or router->post, + but there is a better way described shortly. +

+
+ +
+
+

Running your server

+
+ +

+ To run your server, you can either use the builtin Onyx runtime, or Wasmer with WASIX support. + These are the only two options for now, as there no other runtimes with fully networking support. +

+ +

+ In a later section, you can make this web server use WCGI, so it can be deployed anywhere. +

+ +

+ To run using the Onyx runtime (if it is installed), simply run the following command. +

+
$ onyx run main.onyx
+[Info][Http-Server] Serving on port 8000
+ +

+ To run using Wasmer and WASIX, you need to compile your server to a WASM binary, then + run it with wasmer. +

+
$ # Adding '-r wasi' to target WASI, and '-DWASIX' to add WASIX extensions.
+$ onyx build main.onyx -r wasi -DWASIX
+$ wasmer run --net out.wasm
+[Info][Http-Server] Serving on port 8000
+ +

+ To test your server, you can visit localhost:8000 in your browser. + Or, make a request using cURL. +

+
$ curl http://localhost:8000
+<h1>HTTP Server in Onyx!<h1>
+
+ +
+ +
+
+

Rewriting our code

+
+ +

+ The server you have is perfectly functional, and you could keep adding more routes to it + in the same way as above. However, with all of this code in main, it doesn't + scale terribly well. +

+ +

+ An alternative way to register routes is to use Onyx's procedure tags feature + to label certain procedures as request handlers. Then, the router can automatically find + them and register them! +

+ +

+ Here is how this works. First, you move the request handler from before into a new + global procedure, and add a #tag to it. +

+ +
// Tag the procedure with a `route` structure, so it can be found by the router.
+#tag route.{ .GET, "/" }
+index :: (req: &Request, res: &Response) {
+    // Respond with HTML
+    res->html("

HTTP Server in Onyx!

"); + + // Set status to 200 + res->status(200); + + // Mark the response as completed + res->end(); +}
+ +

+ Now in main, you can remove the router->get() call and replace it with router->collect_routes(). + This procedure will find all route tags in all packages in the code base. +

+ +
main :: () {
+    // Create a router that will route the traffic.
+    router := http.server.router();
+
+    // Collect routes from all packages.
+    router->collect_routes();
+
+    // Create a TCP server out of our router.
+    app := http.server.tcp(&router);
+
+    // Serve on port 8000.
+    app->serve(8000);
+}
+ +

+ You can test the server in the same way as before. +

+
$ onyx run main.onyx
+[Info][Http-Server] Serving on port 8000
+
$ curl http://localhost:8000
+<h1>HTTP Server in Onyx!<h1>
+
+ +
+
+

Deploying to Wasmer Edge

+
+ +

+ To deploy to Wasmer Edge, you need to first convert the code to use + the Common Gateway Interface (CGI) protocol instead of being a TCP server. +

+ +

+ Simply, replace the http.server.tcp call with http.server.cgi. +

+
main :: () {
+    // Create a router that will route the traffic.
+    router := http.server.router();
+
+    // Collect routes from all packages.
+    router->collect_routes();
+
+    // Respond using the CGI protocol
+    http.server.cgi(&router);
+}
+ +

+ Then compile the code to a WebAssembly module targeting the WASI runtime. +

+
$ onyx build main.onyx -r wasi -o my-http-server.wasm 
+ +

+ To deploy to Wasmer Edge, create a wasmer.toml file that contains the following. + Replace <your-namespace> and <your-package-name> with your details. +

+
[package]
+name = "<your-namespace>/<your-package-name>"
+version = "0.1.0"
+description = "My first HTTP server"
+license = "MIT"
+ 
+[[module]]
+name = "server"
+source = "my-http-server.wasm"
+abi = "wasi"
+ 
+[[command]]
+name = "server"
+module = "server"
+runner = "https://webc.org/runner/wcgi"
+ 
+[command.annotations.wasi]
+env = ["SCRIPT_NAME=rust_wcgi"]
+ 
+[command.annotations.wcgi]
+dialect = "rfc-3875"
+ +

+ Also, create an app.yaml file with the following contents. +

+
---
+kind: wasmer.io/App.v0
+name: <your-app-name>
+package: <your-namespace>/<your-package-name>
+ +

+ Then use Wasmer CLI to deploy it. +

+ +
$ wasmer deploy
+ +

+ Follow the instructions from the Wasmer to test your deployment. +

+
+ +
+
+

Next Steps

+
+ +

+ If you want to keep building up your HTTP server, you can look at more examples in the HTTP Server package. +

+
+ + +{{ endblock }} + +{{ extends "pages/normal_page" }} diff --git a/www/templates/pages/docs/guides.html b/www/templates/pages/docs/guides.html new file mode 100644 index 0000000..5235ae7 --- /dev/null +++ b/www/templates/pages/docs/guides.html @@ -0,0 +1,39 @@ +{{block "title"}}Onyx Guides{{endblock}} + +{{ let navbar_page = "docs" }} + +{{ block "page_content" }} + +
+

Guides

+
⇦ Back to the docs
+ +

+ Here is a small list of guides for getting started with common types of Onyx projects. +

+
+ +
+ + +

+ Get started making an HTTP Server, entirely in Onyx. + This guide also descibes how to deploy your server to Wasmer Edge. +

+
+ +
+ + +

+ Get started making games and graphical applications using the popular open source Raylib library. +

+
+ +{{ endblock }} + +{{ extends "pages/normal_page" }} diff --git a/www/templates/pages/docs/install.html b/www/templates/pages/docs/install.html index ff492b6..31b5d7c 100644 --- a/www/templates/pages/docs/install.html +++ b/www/templates/pages/docs/install.html @@ -6,6 +6,7 @@

Installing Onyx

+
⇦ Back to the docs

Online Linux diff --git a/www/templates/pages/docs/package.html b/www/templates/pages/docs/package.html new file mode 100644 index 0000000..bd37c4d --- /dev/null +++ b/www/templates/pages/docs/package.html @@ -0,0 +1,194 @@ +{{block "title"}}Onyx Package Manager{{endblock}} + +{{ let navbar_page = "docs" }} + +{{ block "page_content" }} + +

+

Onyx Package Manager

+ +
+ +
+
+

Philosophy

+
+ +

+ The Onyx package manager is intentionally very simple. + Onyx does not have a central package repository like NPM, PyPI, or Cargo. + Instead Onyx uses a decentralized approach, that follows this simple rule. +

+ +
+ Every package is a Git repository, with a file called module.onyx that is responsible for + including all other files in the package. +
+ +

+ The job of the package manager is to simply clone each of these Git repositories into a known structure, + and build a file for you to include in your project that loads all of your packages. +

+ +

+ The package manager uses Git's tags feature to store version numbers. + This way the package manager can clone exactly one tag, at one commit, to avoid downloading all history of the package, + when all you want is a single version. +

+ +

+ When you publish a package, using onyx package publish it simply increments the version number in the package file, + commits that change, creates a new tag at that commit, and pushes all changes and tags to the Git server. + When someone else runs onyx package update, the new version will be found and updated to. +

+
+ +
+
+

Basic Usage

+
+ +

+ To use Onyx's package manager, you must be in an Onyx project. + An Onyx project is simply a directory with a file named onyx-pkg.kdl. +

+ +

+ To create a new project in a directory, you can use the following command, and answer the prompts (or leave any them blank). +

+
$ onyx package init
+Creating new project manifest in ./onyx-pkg.kdl.
+
+Package name: example-project
+Package description: A simple example project
+Package url: https://github.com/...
+Package author: Brendan Hansen
+Package version (0.0.1):
+ +

Once your project is created, you can add packages by running onyx package add ... +

$ onyx package add http-server
+$ # Or
+$ onyx package add https://github.com/onyx-lang/pkg-http-server
+ +

+ If you want to specify a particular version of a package, you can add the version number as another argument to the command. +

+
$ # Specify version 0.1.2
+$ onyx package add http-server 0.1.2 
+ +

+ For the sake of convience, the package manager maintains a list of string templates to try to resolve where your package comes from. + Currently by default, there is only one, https://github.com/onyx-lang/pkg-X. + This means that when you try to add http-server, it will actually end up using https://github.com/onyx-lang/pkg-http-server. + If you want, you can change this list of string templates at the top of ONYX_PATH/tools/onyx-pkg.onyx. +

+ +

+ You will notice that no files were downloaded and nothing has change in your directory. + This is because adding a package simply adds it to the list of dependencies in your onyx-pkg.kdl + It does not synchronize all of your packages. +

+ +

+ To do that, simply run onyx package sync. +

+
$ onyx package sync
+        Fetch  http://github.com/onyx-lang/pkg-http-server  0.2.24
+ +

+ This downloads all new packages, upgrades exist packages, builds native libraries, and creates a new + package file to include. +

+ +

+ Once all packages are synchroized, you can use them in your project but simplying including the package.onyx + file automatically created. By default this file lives at lib/packages.onyx in your project. +

+ +

+ Here is a simple example of using the http-server package in a project. +

+
// main.onyx
+
+#load "./lib/packages" // <--- Have to include the packages file!
+
+use core
+use http
+
+main :: () {
+    router := http.server.router();
+    router->get("/", (req, res) => {
+        res->html("

Simple server is working!

"); + res->status(200); + res->end(); + }); + + app := http.server.tcp(&router); + app->serve(8000); +}
+ +

+ Once all of this is setup, your workflow will likely just look like onyx pacakge update, then onyx package sync, + with a bit of onyx package add ... sprinkled in there. +

+
+ +
+
+

Creating a Package

+
+ +

+ Creating a new package for Onyx is incredibly simple. + There just three things a project needs to become a package. +

    +
  1. Be a public Git repository
  2. +
  3. Have an onyx-pkg.kdl file
  4. +
  5. Have a module.onyx file
  6. +
+

+ +

+ Hosting a package on GitHub, GitLab, or any Git server is very simple if you are familiar with Git. + Just make sure everyone that needs to access the package has pull access to the repository. +

+ +

+ Every Onyx project already has an onyx-pkg.kdl file. + Ensure the package section has correct information about your package, and you should be good to go there. + See the guide on creating a native library for how to set that up in your project. +

+ +

+ Finally, you need a module.onyx file. + This file simply needs to include all other source files for the package. + In a particularly small package, all of the code might go right inside of module.onyx. +

+ +

+ A typical module.onyx looks like this. +

+
// module.onyx
+
+package package_name_here
+
+#load_all "./src"
+ +

+ This file simply includes everything inside of the src folder. + If needed you can conditionally load source files, depending on your package's needs. +

+ +

+ When your package is ready for a release, you can simply run onyx package publish. + This bumps the version in onyx-pkg.kdl, creates a new commit, tags that commit with the new version, + then pushes all of the changes to the Git server, assuming you have push access. +

+
$ onyx package publish
+  Publishing  Creating new published version
+   Published  Successfully published new version.
+
+ +{{ endblock }} + +{{ extends "pages/normal_page" }} diff --git a/www/templates/pages/docs/package_list.html b/www/templates/pages/docs/package_list.html new file mode 100644 index 0000000..9c71266 --- /dev/null +++ b/www/templates/pages/docs/package_list.html @@ -0,0 +1,82 @@ +{{block "title"}}Onyx Package Manager{{endblock}} + +{{ let navbar_page = "docs" }} + +{{ block "page_content" }} + +
+

Package Listing

+ +
+ +
+
+

First-Party Packages

+
+ +

+ These are official packages hosted on the onyx-lang GitHub account. +

+ + + + + + + + + + + + + + {{ foreach $p in core_packages }} + + + + + {{ endforeach }} + +
PackageDescription
{% p.name %}{% p.description %}
+
+ +
+
+

Third-Party Packages

+
+ + + + + + + + + + + + + + {{ let had_packages = 0 }} + {{ foreach $p in third_party_packages }} + + + + + {{ let had_packages = 1 }} + {{ endforeach }} + {{ if had_packages == 0 }} + + + + + + + {{ endif }} + +
PackageDescription
{% p.name %}{% p.description %}
There are currently no third-party packages.
Create your own package and email me@brendanfh.com to have it added.
+
+ +{{ endblock }} + +{{ extends "pages/normal_page" }} diff --git a/www/templates/pages/homepage.html b/www/templates/pages/homepage.html index 7ecd25e..b226678 100644 --- a/www/templates/pages/homepage.html +++ b/www/templates/pages/homepage.html @@ -8,6 +8,10 @@
+ + {% partial "partials/logo_svg" %} + +

The Onyx Programming Language

-- 2.25.1