This commit is contained in:
2025-09-19 05:35:59 +02:00
parent f54c57847a
commit 1709618f2c
9 changed files with 74 additions and 27 deletions

View File

@@ -8,9 +8,10 @@ fn main() {
// Start the server in a background thread with authentication disabled for testing // Start the server in a background thread with authentication disabled for testing
spawn fn () { spawn fn () {
rpc.start( rpc.start(
port: 8080 port: 8086
auth_enabled: false // Disable auth for testing auth_enabled: false // Disable auth for testing
cors_enabled: true cors_enabled: true
reset: true
allowed_origins: [ allowed_origins: [
'http://localhost:5173', 'http://localhost:5173',
] ]

View File

@@ -5,7 +5,7 @@ import freeflowuniverse.herolib.schemas.openrpc
import os import os
// 1. Create a new server instance // 1. Create a new server instance
mut server := heroserver.new(port: 8080)! mut server := heroserver.new(port: 8086)!
// 2. Create and register your OpenRPC handlers // 2. Create and register your OpenRPC handlers
// These handlers must conform to the `openrpc.OpenRPCHandler` interface. // These handlers must conform to the `openrpc.OpenRPCHandler` interface.
@@ -14,8 +14,8 @@ openrpc_path := os.join_path(script_dir, 'openrpc.json')
handler := openrpc.new_handler(openrpc_path)! handler := openrpc.new_handler(openrpc_path)!
server.register_handler('comments', handler)! server.register_handler('comments', handler)!
println('Server starting on http://localhost:8080') println('Server starting on http://localhost:8086')
println('Documentation available at: http://localhost:8080/doc/comments/') println('Documentation available at: http://localhost:8086/doc/comments/')
println('Comments API available at: http://localhost:8080/api/comments') println('Comments API available at: http://localhost:8086/api/comments')
server.start()! server.start()!

View File

@@ -135,5 +135,7 @@ pub fn (mut self DBCalendar) get(id u32) !Calendar {
} }
pub fn (mut self DBCalendar) list() ![]Calendar { pub fn (mut self DBCalendar) list() ![]Calendar {
return self.db.list[Calendar]()!.map(self.get(it)!) r:= self.db.list[Calendar]()!.map(self.get(it)!)
println(r)
return r
} }

View File

@@ -1,7 +1,13 @@
module heromodels module heromodels
import freeflowuniverse.herolib.hero.db import freeflowuniverse.herolib.hero.db
import freeflowuniverse.herolib.core.redisclient
__global (
rpc_heromodels map[string]&ModelsFactory
)
@[heap]
pub struct ModelsFactory { pub struct ModelsFactory {
pub mut: pub mut:
comments DBComments comments DBComments
@@ -15,9 +21,19 @@ pub mut:
chat_message DBChatMessage chat_message DBChatMessage
} }
pub fn new() !ModelsFactory { @[params]
mut mydb := db.new()! pub struct NewArgs {
return ModelsFactory{ name string @[required]
reset bool
redis ?&redisclient.Redis
}
pub fn new(args NewArgs) !&ModelsFactory {
mut mydb := db.new(redis: args.redis)!
if args.reset {
mydb.redis.flushdb()!
}
mut f := ModelsFactory{
comments: DBComments{ comments: DBComments{
db: &mydb db: &mydb
} }
@@ -46,4 +62,6 @@ pub fn new() !ModelsFactory {
db: &mydb db: &mydb
} }
} }
rpc_heromodels[args.name] = &f
return rpc_heromodels[args.name] or { panic('bug') }
} }

View File

@@ -1,13 +1,13 @@
module rpc module rpc
import freeflowuniverse.herolib.schemas.openrpc import freeflowuniverse.herolib.schemas.openrpc { Handler }
import freeflowuniverse.herolib.hero.heroserver import freeflowuniverse.herolib.hero.heroserver
import os import os
const openrpc_path = os.join_path(os.dir(@FILE), 'openrpc.json') const openrpc_path = os.join_path(os.dir(@FILE), 'openrpc.json')
// Create a new heromodels handler for heroserver // Create a new heromodels handler for heroserver
pub fn new_heromodels_handler() !&openrpc.Handler { pub fn new_heromodels_handler() !&Handler {
mut handler := openrpc.new_handler(openrpc_path)! mut handler := openrpc.new_handler(openrpc_path)!
// Register all comment methods // Register all comment methods
@@ -71,11 +71,13 @@ pub fn new_heromodels_handler() !&openrpc.Handler {
@[params] @[params]
pub struct ServerArgs { pub struct ServerArgs {
pub mut: pub mut:
port int = 8080 port int = 8080
host string = 'localhost' host string = 'localhost'
auth_enabled bool = true auth_enabled bool = true
cors_enabled bool = true cors_enabled bool = true
reset bool
allowed_origins []string = ['*'] // Default allows all origins allowed_origins []string = ['*'] // Default allows all origins
name string
} }
pub fn start(args ServerArgs) ! { pub fn start(args ServerArgs) ! {
@@ -90,6 +92,7 @@ pub fn start(args ServerArgs) ! {
// Create and register the heromodels handler // Create and register the heromodels handler
handler := new_heromodels_handler()! handler := new_heromodels_handler()!
handler.params['name'] = args.name
server.register_handler('heromodels', handler)! server.register_handler('heromodels', handler)!
// Start the server // Start the server

View File

@@ -54,7 +54,7 @@ pub fn calendar_set(request Request) !Response {
events: payload.events events: payload.events
)! )!
calendar_obj=mydb.calendar.set( calendar_obj)! calendar_obj = mydb.calendar.set(calendar_obj)!
return new_response_u32(request.id, calendar_obj.id) return new_response_u32(request.id, calendar_obj.id)
} }
@@ -74,6 +74,5 @@ pub fn calendar_delete(request Request) !Response {
pub fn calendar_list(request Request) !Response { pub fn calendar_list(request Request) !Response {
mut mydb := heromodels.new()! mut mydb := heromodels.new()!
calendars := mydb.calendar.list()! calendars := mydb.calendar.list()!
return jsonrpc.new_response(request.id, json.encode(calendars)) return jsonrpc.new_response(request.id, json.encode(calendars))
} }

View File

@@ -62,12 +62,12 @@ pub mut:
id u32 @[required] id u32 @[required]
} }
pub fn calendar_event_get(request Request) !Response { pub fn calendar_event_get(handlerparams map[string]string, request Request) !Response {
payload := jsonrpc.decode_payload[CalendarEventGetArgs](request.params) or { payload := jsonrpc.decode_payload[CalendarEventGetArgs](request.params) or {
return jsonrpc.invalid_params return jsonrpc.invalid_params
} }
name := handlerparams['name'] or { 'default' }
mut mydb := heromodels.new()! mut mydb := heromodels.get(name)!
calendar_event := mydb.calendar_event.get(payload.id)! calendar_event := mydb.calendar_event.get(payload.id)!
return jsonrpc.new_response(request.id, json.encode(calendar_event)) return jsonrpc.new_response(request.id, json.encode(calendar_event))

View File

@@ -1,9 +1,8 @@
module jsonrpc module jsonrpc
import x.json2 as json import x.json2 as json
import net.websocket
// This file implements a JSON-RPC 2.0 handler for WebSocket servers. // This file implements a JSON-RPC 2.0 handler
// It provides functionality to register procedure handlers and process incoming JSON-RPC requests. // It provides functionality to register procedure handlers and process incoming JSON-RPC requests.
// Handler is a JSON-RPC request handler that maps method names to their corresponding procedure handlers. // Handler is a JSON-RPC request handler that maps method names to their corresponding procedure handlers.
@@ -13,6 +12,7 @@ pub struct Handler {
pub mut: pub mut:
// A map where keys are method names and values are the corresponding procedure handler functions // A map where keys are method names and values are the corresponding procedure handler functions
procedures map[string]ProcedureHandler procedures map[string]ProcedureHandler
params map[string]string
} }
// ProcedureHandler is a function type that processes a JSON-RPC request payload and returns a response. // ProcedureHandler is a function type that processes a JSON-RPC request payload and returns a response.
@@ -84,14 +84,32 @@ pub mut:
} }
pub fn (pw Procedure[T, U]) handle(request Request) !Response { pub fn (pw Procedure[T, U]) handle(request Request) !Response {
payload := decode_payload[T](request.params) or { return invalid_params } payload := decode_payload[T](request.params) or {
result := pw.function(payload) or { return internal_error } RPCError{
code: -32603
message: 'Invalid request params on rpc request.'
data: '${request.params}'
}
}
result := pw.function(payload) or {
return RPCError{
code: -32603
message: 'Error in function on rpc request.'
data: '${request}\n${err}'
}
}
return new_response(request.id, '') return new_response(request.id, '')
} }
pub fn (pw ProcedureVoid[T]) handle(request Request) !Response { pub fn (pw ProcedureVoid[T]) handle(request Request) !Response {
payload := decode_payload[T](request.params) or { return invalid_params } payload := decode_payload[T](request.params) or { return invalid_params }
pw.function(payload) or { return internal_error } result := pw.function(payload) or {
return RPCError{
code: -32603
message: 'Error in function on rpc request.'
data: '${request}\n${err}'
}
}
return new_response(request.id, 'null') return new_response(request.id, 'null')
} }
@@ -145,8 +163,12 @@ pub fn (handler Handler) handle(request Request) !Response {
} }
// Execute the procedure handler with the request payload // Execute the procedure handler with the request payload
return procedure_func(request) or { return procedure_func(handler.params, request) or {
// Return proper JSON-RPC error instead of panicking // Return proper JSON-RPC error instead of panicking
return new_error(request.id, internal_error) return new_error(request.id, RPCError{
code: -32603
message: 'Error in function on rpc request.'
data: '${request}\n${err}'
})
} }
} }

View File

@@ -22,6 +22,8 @@ pub mut:
// An identifier established by the client that must be included in the response // An identifier established by the client that must be included in the response
// This is used to correlate requests with their corresponding responses // This is used to correlate requests with their corresponding responses
id int @[required] id int @[required]
handler_params map[string]string
} }
// new_request creates a new JSON-RPC request with the specified method and parameters. // new_request creates a new JSON-RPC request with the specified method and parameters.