From 8ac82016dd7c96ff854c05cc321e385ad267adeb Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Wed, 25 Feb 2026 12:45:02 -0600 Subject: [PATCH] api for sending wota messages direct --- source/cell.h | 14 ++++++++++++++ source/scheduler.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/source/cell.h b/source/cell.h index e3a15c08..bb3e24dc 100644 --- a/source/cell.h +++ b/source/cell.h @@ -4,6 +4,7 @@ #include #include #include +#include "wota.h" #ifdef __cplusplus extern "C" { @@ -1150,6 +1151,19 @@ JSValue CELL_USE_NAME(JSContext *js) { \ #define CELL_PROGRAM_INIT(c) \ JSValue CELL_USE_NAME(JSContext *js) { do { c ; } while(0); } +/* ============================================================ + WOTA Message Sending — C modules can send messages to actors + without needing a JSContext. + ============================================================ */ + +/* Check whether an actor with the given ID exists. */ +int JS_ActorExists(const char *actor_id); + +/* Send a WOTA-encoded message to an actor by ID. + Takes ownership of wb's data on success (caller must not free). + On failure returns an error string; caller must free wb. */ +const char *JS_SendMessage(const char *actor_id, WotaBuffer *wb); + #undef js_unlikely #undef inline diff --git a/source/scheduler.c b/source/scheduler.c index 599b44c6..49ddea5b 100644 --- a/source/scheduler.c +++ b/source/scheduler.c @@ -1054,3 +1054,31 @@ JSValue actor_remove_timer(JSContext *actor, uint32_t timer_id) // Note: We don't remove from heap, it will misfire safely return cb; } + +int JS_ActorExists(const char *actor_id) +{ + return actor_exists(actor_id); +} + +const char *JS_SendMessage(const char *actor_id, WotaBuffer *wb) +{ + if (!wb || !wb->data || wb->size == 0) + return "Empty WOTA buffer"; + + size_t byte_len = wb->size * sizeof(uint64_t); + blob *msg = blob_new(byte_len * 8); + if (!msg) return "Could not allocate blob"; + + blob_write_bytes(msg, wb->data, byte_len); + blob_make_stone(msg); + + const char *err = send_message(actor_id, msg); + if (!err) { + /* Success — send_message took ownership of the blob. + Free the WotaBuffer internals since we consumed them. */ + wota_buffer_free(wb); + } + /* On failure, send_message already destroyed the blob. + Caller still owns wb and must free it. */ + return err; +}