Frontless-js

Installation

Install Bun if not installed.

curl -fsSL https://bun.sh/install | bash

Create a directory, and initialize your project.

mkdir myserver
cd myserver
bun init

Install frontlessjs.

bun add frontlessjs

Hello World

Create a index.ts in your project

// index.ts
import frontless, { type Widget } from "frontlessjs"
import { text } from "frontlessjs/material"
let app = frontless()
app.page("/", async (): Promise<Widget> => {
      return text("Hello World!")
})
app.listen(3000)

Run your app.

bun index.ts

Then visit localhost:3000 in your browser to see the page!

Router

// index.ts
import frontless, {getCtx,type Widget } from "frontlessjs"
import { text } from "frontlessjs/material"
let app = frontless()

// yourdomain.com
app.page("/", async (): Promise<Widget> => {
      return text("Hello Index!")
})

// yourdomain.com/test
app.page("/test", async (): Promise<Widget> => {
      return text("Hello Test!")
})

// yourdomain.com/post/123, yourdomain.com/post/abc
app.page("/post/[id]", async (): Promise<Widget> => {
      return text("Hello Post: "+getCtx().params.id)
})
app.listen(3000)

Static files

To serve static files, simply create a static folder and put files in to it.

│   index.ts
└───static
│   │   image1.jpg
│   │   image2.jpg

Component

Components are running on server-side, dealing with interactive user interface.

import { Component, useAction } from "frontlessjs";
import { text, column, button } from "frontlessjs/material";

let num = 0
export default Component(async function test(key: { name: string }) {
      let action = useAction(key)
      if (action == 'add') {
            num++
      }
      return column([
            text('name:' + key.name),
            text("num:" + num),
            button(text('Add'), { action: 'add' })
      ])
})

key is sent to user browser. If there are sensitive data in key, you can pick what send to user.

export default Component(async function test(user:{id:string, password:string}) {
      let action = useAction(user,['id'])
      if (action){
            user = select_user_by_id(user.id)
      }
      return text('userId:' + user.id)
})

Context

Context is an object in each request cycle. It is based on asynclocalstorage. You can get ctx from anywhere.

function test(){
      let ctx = getCtx()
}

ctx.body - Object of user posted data.

ctx.query - Object of user query data (url/?foo=bar).

ctx.cookie - Object of user cookie.

ctx.setcookie(name:string,value:string) - Set cookie.

ctx.err(msg:string) - Stop current request and send error message.

ctx.redirect(url:string) - stop current request and redirect user to url.

ctx.req - http.IncomingMessage

ctx.res - http.ServerResponse

Colors

colors is an object contains a set of color widget. You can set shade and saturation for each color.
 text("hello",{color:colors.orange})

Set shade

colors.green.shade(50)
colors.green.shade(100)
colors.green.shade(200)
colors.green.shade(300)
colors.green.shade(400)
colors.green.shade(500)
colors.green.shade(666)
colors.green.shade(777)
colors.red.shade(50)
colors.red.shade(100)
colors.red.shade(200)
colors.red.shade(300)
colors.red.shade(400)
colors.red.shade(500)
colors.red.shade(666)
colors.red.shade(777)
colors.blue.shade(50)
colors.blue.shade(100)
colors.blue.shade(200)
colors.blue.shade(300)
colors.blue.shade(400)
colors.blue.shade(500)
colors.blue.shade(666)
colors.blue.shade(777)

Set saturation

colors.green.saturation(10%)
colors.green.saturation(20%)
colors.green.saturation(30%)
colors.green.saturation(40%)
colors.green.saturation(50%)
colors.green.saturation(60%)
colors.green.saturation(70%)
colors.green.saturation(80%)
colors.red.saturation(10%)
colors.red.saturation(20%)
colors.red.saturation(30%)
colors.red.saturation(40%)
colors.red.saturation(50%)
colors.red.saturation(60%)
colors.red.saturation(70%)
colors.red.saturation(80%)
colors.blue.saturation(10%)
colors.blue.saturation(20%)
colors.blue.saturation(30%)
colors.blue.saturation(40%)
colors.blue.saturation(50%)
colors.blue.saturation(60%)
colors.blue.saturation(70%)
colors.blue.saturation(80%)
Github