diff --git a/examples/hero/heromodels/heroserver_example.vsh b/examples/hero/heromodels/heroserver_example.vsh index 9e715eb9..1024819e 100755 --- a/examples/hero/heromodels/heroserver_example.vsh +++ b/examples/hero/heromodels/heroserver_example.vsh @@ -8,9 +8,10 @@ fn main() { // Start the server in a background thread with authentication disabled for testing spawn fn () { rpc.start( - port: 8080 + port: 8086 auth_enabled: false // Disable auth for testing cors_enabled: true + reset: true allowed_origins: [ 'http://localhost:5173', ] diff --git a/examples/hero/heroserver/heroserver.vsh b/examples/hero/heroserver/heroserver.vsh index f10a1946..f650f2fc 100755 --- a/examples/hero/heroserver/heroserver.vsh +++ b/examples/hero/heroserver/heroserver.vsh @@ -5,7 +5,7 @@ import freeflowuniverse.herolib.schemas.openrpc import os // 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 // 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)! server.register_handler('comments', handler)! -println('Server starting on http://localhost:8080') -println('Documentation available at: http://localhost:8080/doc/comments/') -println('Comments API available at: http://localhost:8080/api/comments') +println('Server starting on http://localhost:8086') +println('Documentation available at: http://localhost:8086/doc/comments/') +println('Comments API available at: http://localhost:8086/api/comments') server.start()! diff --git a/lib/hero/heromodels/calendar.v b/lib/hero/heromodels/calendar.v index e5ebfeab..4cbd6523 100644 --- a/lib/hero/heromodels/calendar.v +++ b/lib/hero/heromodels/calendar.v @@ -135,5 +135,7 @@ pub fn (mut self DBCalendar) get(id u32) !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 } diff --git a/lib/hero/heromodels/factory.v b/lib/hero/heromodels/factory.v index a202d6d4..3c83cd83 100644 --- a/lib/hero/heromodels/factory.v +++ b/lib/hero/heromodels/factory.v @@ -1,7 +1,13 @@ module heromodels import freeflowuniverse.herolib.hero.db +import freeflowuniverse.herolib.core.redisclient +__global ( + rpc_heromodels map[string]&ModelsFactory +) + +@[heap] pub struct ModelsFactory { pub mut: comments DBComments @@ -15,9 +21,19 @@ pub mut: chat_message DBChatMessage } -pub fn new() !ModelsFactory { - mut mydb := db.new()! - return ModelsFactory{ +@[params] +pub struct NewArgs { + 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{ db: &mydb } @@ -46,4 +62,6 @@ pub fn new() !ModelsFactory { db: &mydb } } + rpc_heromodels[args.name] = &f + return rpc_heromodels[args.name] or { panic('bug') } } diff --git a/lib/hero/heromodels/rpc/factory.v b/lib/hero/heromodels/rpc/factory.v index b065e048..f313d05e 100644 --- a/lib/hero/heromodels/rpc/factory.v +++ b/lib/hero/heromodels/rpc/factory.v @@ -1,13 +1,13 @@ module rpc -import freeflowuniverse.herolib.schemas.openrpc +import freeflowuniverse.herolib.schemas.openrpc { Handler } import freeflowuniverse.herolib.hero.heroserver import os const openrpc_path = os.join_path(os.dir(@FILE), 'openrpc.json') // 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)! // Register all comment methods @@ -71,11 +71,13 @@ pub fn new_heromodels_handler() !&openrpc.Handler { @[params] pub struct ServerArgs { pub mut: - port int = 8080 - host string = 'localhost' - auth_enabled bool = true - cors_enabled bool = true + port int = 8080 + host string = 'localhost' + auth_enabled bool = true + cors_enabled bool = true + reset bool allowed_origins []string = ['*'] // Default allows all origins + name string } pub fn start(args ServerArgs) ! { @@ -90,6 +92,7 @@ pub fn start(args ServerArgs) ! { // Create and register the heromodels handler handler := new_heromodels_handler()! + handler.params['name'] = args.name server.register_handler('heromodels', handler)! // Start the server diff --git a/lib/hero/heromodels/rpc/rpc_calendar.v b/lib/hero/heromodels/rpc/rpc_calendar.v index f6be62a5..e58fb603 100644 --- a/lib/hero/heromodels/rpc/rpc_calendar.v +++ b/lib/hero/heromodels/rpc/rpc_calendar.v @@ -54,7 +54,7 @@ pub fn calendar_set(request Request) !Response { 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) } @@ -74,6 +74,5 @@ pub fn calendar_delete(request Request) !Response { pub fn calendar_list(request Request) !Response { mut mydb := heromodels.new()! calendars := mydb.calendar.list()! - return jsonrpc.new_response(request.id, json.encode(calendars)) } diff --git a/lib/hero/heromodels/rpc/rpc_calendar_event.v b/lib/hero/heromodels/rpc/rpc_calendar_event.v index 7a993835..90e889ce 100644 --- a/lib/hero/heromodels/rpc/rpc_calendar_event.v +++ b/lib/hero/heromodels/rpc/rpc_calendar_event.v @@ -62,12 +62,12 @@ pub mut: 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 { return jsonrpc.invalid_params } - - mut mydb := heromodels.new()! + name := handlerparams['name'] or { 'default' } + mut mydb := heromodels.get(name)! calendar_event := mydb.calendar_event.get(payload.id)! return jsonrpc.new_response(request.id, json.encode(calendar_event)) diff --git a/lib/schemas/jsonrpc/handler.v b/lib/schemas/jsonrpc/handler.v index 57720ba5..d2a16f19 100644 --- a/lib/schemas/jsonrpc/handler.v +++ b/lib/schemas/jsonrpc/handler.v @@ -1,9 +1,8 @@ module jsonrpc 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. // 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: // A map where keys are method names and values are the corresponding procedure handler functions procedures map[string]ProcedureHandler + params map[string]string } // 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 { - payload := decode_payload[T](request.params) or { return invalid_params } - result := pw.function(payload) or { return internal_error } + payload := decode_payload[T](request.params) or { + 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, '') } pub fn (pw ProcedureVoid[T]) handle(request Request) !Response { 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') } @@ -145,8 +163,12 @@ pub fn (handler Handler) handle(request Request) !Response { } // 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 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}' + }) } } diff --git a/lib/schemas/jsonrpc/model_request.v b/lib/schemas/jsonrpc/model_request.v index f4c39021..45bd294c 100644 --- a/lib/schemas/jsonrpc/model_request.v +++ b/lib/schemas/jsonrpc/model_request.v @@ -22,6 +22,8 @@ pub mut: // An identifier established by the client that must be included in the response // This is used to correlate requests with their corresponding responses id int @[required] + + handler_params map[string]string } // new_request creates a new JSON-RPC request with the specified method and parameters.