mirror of
https://github.com/cf-sonr/motr.git
synced 2026-01-12 11:09:13 +00:00
feat: migrate to go-wasm-http-server and Taskfile for improved workflow
This commit is contained in:
20
Makefile
20
Makefile
@@ -1,20 +0,0 @@
|
||||
|
||||
VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//')
|
||||
COMMIT := $(shell git log -1 --format='%H')
|
||||
|
||||
.PHONY: all build generate test
|
||||
|
||||
all: generate build
|
||||
|
||||
build:
|
||||
rm -rf src/vault.wasm
|
||||
@GOOS=js GOARCH=wasm go build -o src/vault.wasm .
|
||||
|
||||
generate:
|
||||
@templ generate
|
||||
@sqlc generate -f "x/identity/model/sqlc.yaml"
|
||||
@sqlc generate -f "x/portfolio/model/sqlc.yaml"
|
||||
@sqlc generate -f "x/user/model/sqlc.yaml"
|
||||
|
||||
test:
|
||||
@go test -v ./...
|
||||
66
Taskfile.yml
Normal file
66
Taskfile.yml
Normal file
@@ -0,0 +1,66 @@
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/taskfile
|
||||
version: "3"
|
||||
silent: true
|
||||
|
||||
# vars:
|
||||
# VERSION:
|
||||
# sh: git describe --tags
|
||||
# COMMIT:
|
||||
# sh: git log -1 --format='%H'
|
||||
#
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- task: gen:templ
|
||||
- task: gen:sqlc
|
||||
- task: build
|
||||
|
||||
gen:templ:
|
||||
desc: Generate code
|
||||
sources:
|
||||
- "**/*.templ"
|
||||
generates:
|
||||
- "**/*_templ.go"
|
||||
cmds:
|
||||
- templ generate
|
||||
|
||||
gen:sqlc:
|
||||
desc: Generate code
|
||||
sources:
|
||||
- x/**/model/*.sql
|
||||
generates:
|
||||
- x/**/model/*.go
|
||||
cmds:
|
||||
- sqlc generate -f "x/identity/model/sqlc.yaml"
|
||||
- sqlc generate -f "x/portfolio/model/sqlc.yaml"
|
||||
- sqlc generate -f "x/user/model/sqlc.yaml"
|
||||
|
||||
build:
|
||||
desc: Build
|
||||
watch: true
|
||||
sources:
|
||||
- "**/*.go"
|
||||
generates:
|
||||
- web/vault.wasm
|
||||
deps:
|
||||
- task: gen:templ
|
||||
- task: gen:sqlc
|
||||
vars:
|
||||
TIME:
|
||||
sh: date
|
||||
cmds:
|
||||
- rm -rf web/vault.wasm
|
||||
- GOOS=js GOARCH=wasm go build -o web/vault.wasm .
|
||||
- gum log --time rfc822 --level info "[BUILD] WASM Complete"
|
||||
|
||||
serve:
|
||||
desc: Serve
|
||||
dir: web
|
||||
cmds:
|
||||
- bunx live-server
|
||||
|
||||
test:
|
||||
desc: Test
|
||||
cmds:
|
||||
- go test -v ./...
|
||||
26
app/app.go
26
app/app.go
@@ -4,34 +4,42 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/identity"
|
||||
"github.com/onsonr/motr/x/portfolio"
|
||||
"github.com/onsonr/motr/x/user"
|
||||
)
|
||||
|
||||
// New returns a new App instance
|
||||
func New(opts ...Option) (*App, error) {
|
||||
o := baseOptions()
|
||||
for _, opt := range opts {
|
||||
opt(o)
|
||||
}
|
||||
e := o.applyDefaults()
|
||||
|
||||
identity.RegisterRoutes(e, o.conn.Identity)
|
||||
portfolio.RegisterRoutes(e, o.conn.Portfolio)
|
||||
user.RegisterRoutes(e, o.conn.User)
|
||||
//
|
||||
// identity.RegisterRoutes(e, o.conn.Identity)
|
||||
// portfolio.RegisterRoutes(e, o.conn.Portfolio)
|
||||
// user.RegisterRoutes(e, o.conn.User)
|
||||
|
||||
return &App{
|
||||
Config: o.cfg,
|
||||
Database: o.conn,
|
||||
e: e,
|
||||
Echo: e,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// handleIndex returns a simple JSON response
|
||||
func handleIndex(c echo.Context) error {
|
||||
return c.String(200, "Hello, World!")
|
||||
params := make(map[string]string)
|
||||
if err := json.NewDecoder(c.Request().Body).Decode(¶ms); err != nil {
|
||||
return c.JSON(400, map[string]string{"message": err.Error()})
|
||||
}
|
||||
|
||||
c.Response().Header().Set("Content-Type", "application/json")
|
||||
return c.JSON(200, map[string]string{"message": "Hello, World!"})
|
||||
}
|
||||
|
||||
// handleError returns a simple JSON response
|
||||
func handleError() echo.HTTPErrorHandler {
|
||||
return func(err error, c echo.Context) {
|
||||
if he, ok := err.(*echo.HTTPError); ok {
|
||||
|
||||
@@ -6,18 +6,13 @@ package app
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
echomiddleware "github.com/labstack/echo/v4/middleware"
|
||||
"github.com/onsonr/motr/internal/serve"
|
||||
"github.com/onsonr/motr/pkg/config"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
Config *config.MotrConfig
|
||||
Database *config.DBConnection
|
||||
e *echo.Echo
|
||||
}
|
||||
|
||||
func (a *App) Start() {
|
||||
serve.Fetch(a.e)
|
||||
Echo *echo.Echo
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
@@ -33,8 +28,8 @@ func (o *Options) applyDefaults() *echo.Echo {
|
||||
for _, mdw := range o.mdws {
|
||||
e.Use(mdw)
|
||||
}
|
||||
e.GET("/", handleIndex)
|
||||
return nil
|
||||
e.POST("/", handleIndex)
|
||||
return e
|
||||
}
|
||||
|
||||
func baseOptions() *Options {
|
||||
@@ -48,18 +43,21 @@ func baseOptions() *Options {
|
||||
|
||||
type Option func(*Options)
|
||||
|
||||
// WithConfig sets the configuration for the application
|
||||
func WithConfig(cfg *config.MotrConfig) func(*Options) {
|
||||
return func(o *Options) {
|
||||
o.cfg = cfg
|
||||
}
|
||||
}
|
||||
|
||||
// WithDatabase sets the database connection for the application
|
||||
func WithDatabase(conn *config.DBConnection) func(*Options) {
|
||||
return func(o *Options) {
|
||||
o.conn = conn
|
||||
}
|
||||
}
|
||||
|
||||
// WithMiddleware sets the middleware for the application
|
||||
func WithMiddleware(mdws ...echo.MiddlewareFunc) func(*Options) {
|
||||
return func(o *Options) {
|
||||
o.mdws = append(o.mdws, mdws...)
|
||||
|
||||
6
go.mod
6
go.mod
@@ -6,6 +6,12 @@ require (
|
||||
github.com/a-h/templ v0.3.857
|
||||
github.com/labstack/echo/v4 v4.13.3
|
||||
github.com/ncruces/go-sqlite3 v0.21.3
|
||||
github.com/nlepage/go-wasm-http-server/v2 v2.2.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/hack-pad/safejs v0.1.1 // indirect
|
||||
github.com/nlepage/go-js-promise v1.0.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
6
go.sum
6
go.sum
@@ -4,6 +4,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/hack-pad/safejs v0.1.1 h1:d5qPO0iQ7h2oVtpzGnLExE+Wn9AtytxIfltcS2b9KD8=
|
||||
github.com/hack-pad/safejs v0.1.1/go.mod h1:HdS+bKF1NrE72VoXZeWzxFOVQVUSqZJAG0xNCnb+Tio=
|
||||
github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
|
||||
github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
@@ -17,6 +19,10 @@ github.com/ncruces/go-sqlite3 v0.21.3 h1:hHkfNQLcbnxPJZhC/RGw9SwP3bfkv/Y0xUHWsr1
|
||||
github.com/ncruces/go-sqlite3 v0.21.3/go.mod h1:zxMOaSG5kFYVFK4xQa0pdwIszqxqJ0W0BxBgwdrNjuA=
|
||||
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
|
||||
github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g=
|
||||
github.com/nlepage/go-js-promise v1.0.0 h1:K7OmJ3+0BgWJ2LfXchg2sI6RDr7AW/KWR8182epFwGQ=
|
||||
github.com/nlepage/go-js-promise v1.0.0/go.mod h1:bdOP0wObXu34euibyK39K1hoBCtlgTKXGc56AGflaRo=
|
||||
github.com/nlepage/go-wasm-http-server/v2 v2.2.1 h1:4tzhSb3HKQ3Ykt2TPfqEnmcPfw8n1E8agv4OzAyckr8=
|
||||
github.com/nlepage/go-wasm-http-server/v2 v2.2.1/go.mod h1:r8j7cEOeUqNp+c+C52sNuWaFTvvT/cNqIwBuEtA36HA=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
package serve
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall/js"
|
||||
)
|
||||
|
||||
var (
|
||||
// Global buffer pool to reduce allocations
|
||||
bufferPool = sync.Pool{
|
||||
New: func() any {
|
||||
return new(bytes.Buffer)
|
||||
},
|
||||
}
|
||||
|
||||
// Cached JS globals
|
||||
jsGlobal = js.Global()
|
||||
jsUint8Array = jsGlobal.Get("Uint8Array")
|
||||
jsResponse = jsGlobal.Get("Response")
|
||||
jsPromise = jsGlobal.Get("Promise")
|
||||
jsWasmHTTP = jsGlobal.Get("wasmhttp")
|
||||
)
|
||||
|
||||
// Fetch serves HTTP requests with optimized handler management
|
||||
func Fetch(handler http.Handler) func() {
|
||||
h := handler
|
||||
if h == nil {
|
||||
h = http.DefaultServeMux
|
||||
}
|
||||
|
||||
// Optimize prefix handling
|
||||
prefix := strings.TrimRight(jsWasmHTTP.Get("path").String(), "/")
|
||||
if prefix != "" {
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle(prefix+"/", http.StripPrefix(prefix, h))
|
||||
h = mux
|
||||
}
|
||||
|
||||
// Create request handler function
|
||||
cb := js.FuncOf(func(_ js.Value, args []js.Value) any {
|
||||
promise, resolve, reject := newPromiseOptimized()
|
||||
|
||||
go handleRequest(h, args[1], resolve, reject)
|
||||
|
||||
return promise
|
||||
})
|
||||
|
||||
jsWasmHTTP.Call("setHandler", cb)
|
||||
return cb.Release
|
||||
}
|
||||
|
||||
// handleRequest processes the request with panic recovery
|
||||
func handleRequest(h http.Handler, jsReq js.Value, resolve, reject func(any)) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
var errMsg string
|
||||
if err, ok := r.(error); ok {
|
||||
errMsg = fmt.Sprintf("wasmhttp: panic: %+v", err)
|
||||
} else {
|
||||
errMsg = fmt.Sprintf("wasmhttp: panic: %v", r)
|
||||
}
|
||||
reject(errMsg)
|
||||
}
|
||||
}()
|
||||
|
||||
recorder := newResponseRecorder()
|
||||
h.ServeHTTP(recorder, buildRequest(jsReq))
|
||||
resolve(recorder.jsResponse())
|
||||
}
|
||||
|
||||
// buildRequest creates an http.Request from JS Request
|
||||
func buildRequest(jsReq js.Value) *http.Request {
|
||||
// Get request body
|
||||
arrayBuffer, err := awaitPromiseOptimized(jsReq.Call("arrayBuffer"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Create body buffer
|
||||
jsBody := jsUint8Array.New(arrayBuffer)
|
||||
bodyLen := jsBody.Get("length").Int()
|
||||
body := make([]byte, bodyLen)
|
||||
js.CopyBytesToGo(body, jsBody)
|
||||
|
||||
// Create request
|
||||
req := httptest.NewRequest(
|
||||
jsReq.Get("method").String(),
|
||||
jsReq.Get("url").String(),
|
||||
bytes.NewReader(body),
|
||||
)
|
||||
|
||||
// Set headers efficiently
|
||||
headers := jsReq.Get("headers")
|
||||
headersIt := headers.Call("entries")
|
||||
for {
|
||||
entry := headersIt.Call("next")
|
||||
if entry.Get("done").Bool() {
|
||||
break
|
||||
}
|
||||
pair := entry.Get("value")
|
||||
req.Header.Set(pair.Index(0).String(), pair.Index(1).String())
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
// ResponseRecorder with optimized buffer handling
|
||||
type ResponseRecorder struct {
|
||||
*httptest.ResponseRecorder
|
||||
buffer *bytes.Buffer
|
||||
}
|
||||
|
||||
func newResponseRecorder() *ResponseRecorder {
|
||||
return &ResponseRecorder{
|
||||
ResponseRecorder: httptest.NewRecorder(),
|
||||
buffer: bufferPool.Get().(*bytes.Buffer),
|
||||
}
|
||||
}
|
||||
|
||||
// jsResponse creates a JS Response with optimized memory usage
|
||||
func (rr *ResponseRecorder) jsResponse() js.Value {
|
||||
defer func() {
|
||||
rr.buffer.Reset()
|
||||
bufferPool.Put(rr.buffer)
|
||||
}()
|
||||
|
||||
res := rr.Result()
|
||||
defer res.Body.Close()
|
||||
|
||||
// Prepare response body
|
||||
body := js.Undefined()
|
||||
if res.ContentLength != 0 {
|
||||
if _, err := io.Copy(rr.buffer, res.Body); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bodyBytes := rr.buffer.Bytes()
|
||||
body = jsUint8Array.New(len(bodyBytes))
|
||||
js.CopyBytesToJS(body, bodyBytes)
|
||||
}
|
||||
|
||||
// Prepare response init object
|
||||
init := make(map[string]any, 3)
|
||||
if res.StatusCode != 0 {
|
||||
init["status"] = res.StatusCode
|
||||
}
|
||||
|
||||
if len(res.Header) > 0 {
|
||||
headers := make(map[string]any, len(res.Header))
|
||||
for k, v := range res.Header {
|
||||
if len(v) > 0 {
|
||||
headers[k] = v[0]
|
||||
}
|
||||
}
|
||||
init["headers"] = headers
|
||||
}
|
||||
|
||||
return jsResponse.New(body, init)
|
||||
}
|
||||
|
||||
// newPromiseOptimized creates a new JavaScript Promise with optimized callback handling
|
||||
func newPromiseOptimized() (js.Value, func(any), func(any)) {
|
||||
var (
|
||||
resolve func(any)
|
||||
reject func(any)
|
||||
promiseFunc = js.FuncOf(func(_ js.Value, args []js.Value) any {
|
||||
resolve = func(v any) { args[0].Invoke(v) }
|
||||
reject = func(v any) { args[1].Invoke(v) }
|
||||
return js.Undefined()
|
||||
})
|
||||
)
|
||||
defer promiseFunc.Release()
|
||||
|
||||
return jsPromise.New(promiseFunc), resolve, reject
|
||||
}
|
||||
|
||||
// awaitPromiseOptimized waits for Promise resolution with optimized channel handling
|
||||
func awaitPromiseOptimized(promise js.Value) (js.Value, error) {
|
||||
done := make(chan struct{})
|
||||
var (
|
||||
result js.Value
|
||||
err error
|
||||
)
|
||||
|
||||
thenFunc := js.FuncOf(func(_ js.Value, args []js.Value) any {
|
||||
result = args[0]
|
||||
close(done)
|
||||
return nil
|
||||
})
|
||||
defer thenFunc.Release()
|
||||
|
||||
catchFunc := js.FuncOf(func(_ js.Value, args []js.Value) any {
|
||||
err = js.Error{Value: args[0]}
|
||||
close(done)
|
||||
return nil
|
||||
})
|
||||
defer catchFunc.Release()
|
||||
|
||||
promise.Call("then", thenFunc).Call("catch", catchFunc)
|
||||
<-done
|
||||
|
||||
return result, err
|
||||
}
|
||||
7
main.go
7
main.go
@@ -6,23 +6,22 @@ package main
|
||||
import (
|
||||
"log"
|
||||
|
||||
wasmhttp "github.com/nlepage/go-wasm-http-server/v2"
|
||||
"github.com/onsonr/motr/app"
|
||||
"github.com/onsonr/motr/internal/context"
|
||||
"github.com/onsonr/motr/internal/database"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// configString := "TODO"
|
||||
// config, _ := loadConfig(configString)
|
||||
dbq, err := database.New()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
e, err := app.New(app.WithDatabase(dbq), app.WithMiddleware(context.WASMMiddleware))
|
||||
_, err = app.New(app.WithDatabase(dbq))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
e.Start()
|
||||
wasmhttp.Serve(nil)
|
||||
}
|
||||
|
||||
57
src/sw.js
57
src/sw.js
@@ -1,57 +0,0 @@
|
||||
// Note the 'go.1.23.4' below, that matches the version you just found:
|
||||
importScripts('https://cdn.jsdelivr.net/gh/golang/go@go1.24.1/misc/wasm/wasm_exec.js')
|
||||
|
||||
const wasm = 'vault.wasm'
|
||||
|
||||
function registerWasmHTTPListener(wasm, { base, cacheName, passthrough, args = [] } = {}) {
|
||||
let path = new URL(registration.scope).pathname
|
||||
if (base && base !== '') path = `${trimEnd(path, '/')}/${trimStart(base, '/')}`
|
||||
|
||||
const handlerPromise = new Promise(setHandler => {
|
||||
self.wasmhttp = {
|
||||
path,
|
||||
setHandler,
|
||||
}
|
||||
})
|
||||
|
||||
const go = new Go()
|
||||
go.argv = [wasm, ...args]
|
||||
const source = cacheName
|
||||
? caches.open(cacheName).then((cache) => cache.match(wasm)).then((response) => response ?? fetch(wasm))
|
||||
: caches.match(wasm).then(response => (response) ?? fetch(wasm))
|
||||
WebAssembly.instantiateStreaming(source, go.importObject).then(({ instance }) => go.run(instance))
|
||||
|
||||
addEventListener('fetch', e => {
|
||||
if (passthrough?.(e.request)) {
|
||||
e.respondWith(fetch(e.request))
|
||||
return;
|
||||
}
|
||||
|
||||
const { pathname } = new URL(e.request.url)
|
||||
if (!pathname.startsWith(path)) return
|
||||
|
||||
e.respondWith(handlerPromise.then(handler => handler(e.request)))
|
||||
})
|
||||
}
|
||||
|
||||
function trimStart(s, c) {
|
||||
let r = s
|
||||
while (r.startsWith(c)) r = r.slice(c.length)
|
||||
return r
|
||||
}
|
||||
|
||||
function trimEnd(s, c) {
|
||||
let r = s
|
||||
while (r.endsWith(c)) r = r.slice(0, -c.length)
|
||||
return r
|
||||
}
|
||||
|
||||
addEventListener('install', (event) => {
|
||||
event.waitUntil(caches.open('dwn').then((cache) => cache.add(wasm)))
|
||||
})
|
||||
|
||||
addEventListener('activate', (event) => {
|
||||
event.waitUntil(clients.claim())
|
||||
})
|
||||
|
||||
registerWasmHTTPListener(wasm, { base: 'vault' })
|
||||
27
web/bun.lock
Normal file
27
web/bun.lock
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "motr",
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@types/bun": ["@types/bun@1.2.8", "", { "dependencies": { "bun-types": "1.2.7" } }, "sha512-t8L1RvJVUghW5V+M/fL3Thbxcs0HwNsXsnTEBEfEVqGteiJToOlZ/fyOEaR1kZsNqnu+3XA4RI/qmnX4w6+S+w=="],
|
||||
|
||||
"@types/node": ["@types/node@22.14.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA=="],
|
||||
|
||||
"@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
|
||||
|
||||
"bun-types": ["bun-types@1.2.7", "", { "dependencies": { "@types/node": "*", "@types/ws": "*" } }, "sha512-P4hHhk7kjF99acXqKvltyuMQ2kf/rzIw3ylEDpCxDS9Xa0X0Yp/gJu/vDCucmWpiur5qJ0lwB2bWzOXa2GlHqA=="],
|
||||
|
||||
"typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="],
|
||||
|
||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
async function hello() {
|
||||
const name = document.querySelector("#name").value;
|
||||
|
||||
const res = await fetch("api/hello", {
|
||||
const res = await fetch("vault", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
15
web/sw.js
Normal file
15
web/sw.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// Note the 'go.1.23.4' below, that matches the version you just found:
|
||||
importScripts('https://cdn.jsdelivr.net/gh/golang/go@go1.23.1/misc/wasm/wasm_exec.js')
|
||||
importScripts('https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v2.2.1/sw.js')
|
||||
|
||||
const wasm = 'vault.wasm'
|
||||
|
||||
addEventListener('install', (event) => {
|
||||
event.waitUntil(caches.open('dwn').then((cache) => cache.add(wasm)))
|
||||
})
|
||||
|
||||
addEventListener('activate', (event) => {
|
||||
event.waitUntil(clients.claim())
|
||||
})
|
||||
|
||||
registerWasmHTTPListener(wasm, { base: 'vault' })
|
||||
@@ -1,16 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/identity/model"
|
||||
)
|
||||
|
||||
func HandleAccounts(g *echo.Group, m *model.Queries) {
|
||||
g.Any("/accounts", accountHandler(m))
|
||||
}
|
||||
|
||||
func accountHandler(m *model.Queries) func(e echo.Context) error {
|
||||
return func(e echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/identity/model"
|
||||
)
|
||||
|
||||
func HandleCredentials(g *echo.Group, m *model.Queries) {
|
||||
g.Any("/credentials", credentialsHandler(m))
|
||||
}
|
||||
|
||||
func credentialsHandler(m *model.Queries) func(e echo.Context) error {
|
||||
return func(e echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/identity/model"
|
||||
)
|
||||
|
||||
func HandleDevices(g *echo.Group, m *model.Queries) {
|
||||
g.Any("/devices", devicesHandler(m))
|
||||
}
|
||||
|
||||
func devicesHandler(m *model.Queries) func(e echo.Context) error {
|
||||
return func(e echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/identity/controller"
|
||||
"github.com/onsonr/motr/x/identity/model"
|
||||
"github.com/onsonr/motr/x/identity/view"
|
||||
)
|
||||
@@ -24,10 +23,10 @@ func InitTables(db *sql.DB) (Model, error) {
|
||||
|
||||
func RegisterRoutes(e *echo.Echo, m Model, mdws ...echo.MiddlewareFunc) {
|
||||
// API Routes
|
||||
g := e.Group("/api/identity/v1")
|
||||
controller.HandleAccounts(g, m)
|
||||
controller.HandleCredentials(g, m)
|
||||
controller.HandleDevices(g, m)
|
||||
// g := e.Group("/api/identity/v1")
|
||||
// controller.HandleAccounts(g, m)
|
||||
// controller.HandleCredentials(g, m)
|
||||
// controller.HandleDevices(g, m)
|
||||
|
||||
// View Routes
|
||||
e.GET("/authorize", view.HandleView)
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/portfolio/model"
|
||||
)
|
||||
|
||||
func HandleAssets(g *echo.Group, m *model.Queries) {
|
||||
g.Any("/assets", assetHandler(m))
|
||||
}
|
||||
|
||||
func assetHandler(m *model.Queries) func(e echo.Context) error {
|
||||
return func(e echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/portfolio/model"
|
||||
)
|
||||
|
||||
func HandleBalances(g *echo.Group, m *model.Queries) {
|
||||
g.Any("/balances", balanceHandler(m))
|
||||
}
|
||||
|
||||
func balanceHandler(m *model.Queries) func(e echo.Context) error {
|
||||
return func(e echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/portfolio/model"
|
||||
)
|
||||
|
||||
func HandleChains(g *echo.Group, m *model.Queries) {
|
||||
g.Any("/chains", chainsHandler(m))
|
||||
}
|
||||
|
||||
func chainsHandler(m *model.Queries) func(e echo.Context) error {
|
||||
return func(e echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/portfolio/controller"
|
||||
"github.com/onsonr/motr/x/portfolio/model"
|
||||
"github.com/onsonr/motr/x/portfolio/view"
|
||||
)
|
||||
@@ -24,10 +23,10 @@ func InitTables(db *sql.DB) (Model, error) {
|
||||
|
||||
func RegisterRoutes(e *echo.Echo, m Model, mdws ...echo.MiddlewareFunc) {
|
||||
// API Routes
|
||||
g := e.Group("/api/portfolio/v1")
|
||||
controller.HandleAssets(g, m)
|
||||
controller.HandleBalances(g, m)
|
||||
controller.HandleChains(g, m)
|
||||
// g := e.Group("/api/portfolio/v1")
|
||||
// controller.HandleAssets(g, m)
|
||||
// controller.HandleBalances(g, m)
|
||||
// controller.HandleChains(g, m)
|
||||
|
||||
// View Routes
|
||||
e.GET("/allocation", view.HandleView)
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/user/model"
|
||||
)
|
||||
|
||||
func HandleProfiles(g *echo.Group, m *model.Queries) {
|
||||
g.Any("/assets", profileHandler(m))
|
||||
}
|
||||
|
||||
func profileHandler(m *model.Queries) func(e echo.Context) error {
|
||||
return func(e echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/user/model"
|
||||
)
|
||||
|
||||
func HandleSessions(g *echo.Group, m *model.Queries) {
|
||||
g.Any("/sessions", sessionHandler(m))
|
||||
}
|
||||
|
||||
func sessionHandler(m *model.Queries) func(e echo.Context) error {
|
||||
return func(e echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/user/model"
|
||||
)
|
||||
|
||||
func HandleVault(g *echo.Group, m *model.Queries) {
|
||||
g.Any("/vault", vaultHandler(m))
|
||||
}
|
||||
|
||||
func vaultHandler(m *model.Queries) func(e echo.Context) error {
|
||||
return func(e echo.Context) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/onsonr/motr/x/user/controller"
|
||||
"github.com/onsonr/motr/x/user/model"
|
||||
"github.com/onsonr/motr/x/user/view"
|
||||
)
|
||||
@@ -23,12 +22,12 @@ func InitTables(db *sql.DB) (Model, error) {
|
||||
}
|
||||
|
||||
func RegisterRoutes(e *echo.Echo, m Model, mdws ...echo.MiddlewareFunc) {
|
||||
// API Routes
|
||||
g := e.Group("/api/user/v1")
|
||||
controller.HandleProfiles(g, m)
|
||||
controller.HandleSessions(g, m)
|
||||
controller.HandleVault(g, m)
|
||||
|
||||
// // API Routes
|
||||
// g := e.Group("/api/user/v1")
|
||||
// controller.HandleProfiles(g, m)
|
||||
// controller.HandleSessions(g, m)
|
||||
// controller.HandleVault(g, m)
|
||||
//
|
||||
// View Routes
|
||||
e.GET("/dashboard", view.HandleView)
|
||||
e.GET("/settings", view.HandleView)
|
||||
|
||||
Reference in New Issue
Block a user