Expose ssb.following to JS.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4588 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
Cory McWilliams 2023-10-29 19:05:32 +00:00
parent 4a1d136721
commit b394140f9e

View File

@ -1512,6 +1512,96 @@ static JSValue _tf_ssb_private_message_decrypt(JSContext* context, JSValueConst
return result;
}
typedef struct _following_t
{
uv_work_t work;
tf_ssb_t* ssb;
JSContext* context;
JSValue promise[2];
const char** out_ids;
int depth;
int ids_count;
const char* ids[];
} following_t;
static void _tf_ssb_following_work(uv_work_t* work)
{
following_t* following = work->data;
following->out_ids = tf_ssb_db_following_deep(following->ssb, following->ids, following->ids_count, following->depth);
}
static void _tf_ssb_following_after_work(uv_work_t* work, int status)
{
following_t* following = work->data;
JSContext* context = following->context;
if (status == 0)
{
JSValue array = JS_NewArray(context);
for (int i = 0; following->out_ids[i]; i++)
{
JS_SetPropertyUint32(context, array, i, JS_NewString(context, following->out_ids[i]));
}
JS_Call(context, following->promise[0], JS_UNDEFINED, 1, &array);
JS_FreeValue(context, array);
}
else
{
char buffer[256];
uv_strerror_r(status, buffer, sizeof(buffer));
JSValue message = JS_NewString(context, buffer);
JS_Call(context, following->promise[1], JS_UNDEFINED, 1, &message);
JS_FreeValue(context, message);
}
for (int i = 0; i < following->ids_count; i++)
{
tf_free((void*)following->ids[i]);
}
tf_free(following->out_ids);
tf_free(following);
}
static JSValue _tf_ssb_following(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
int ids_count = tf_util_get_length(context, argv[0]);
following_t* following = tf_malloc(sizeof(following_t) + sizeof(char*) * ids_count);
*following = (following_t)
{
.work =
{
.data = following,
},
.context = context,
.ssb = ssb,
};
JS_ToInt32(context, &following->depth, argv[1]);
JSValue result = JS_NewPromiseCapability(context, following->promise);
for (int i = 0; i < ids_count; i++)
{
JSValue id_value = JS_GetPropertyUint32(context, argv[0], i);
if (!JS_IsUndefined(id_value))
{
const char* id_string = JS_ToCString(context, id_value);
following->ids[following->ids_count++] = tf_strdup(id_string);
JS_FreeCString(context, id_string);
JS_FreeValue(context, id_value);
}
}
int r = uv_queue_work(tf_ssb_get_loop(ssb), &following->work, _tf_ssb_following_work, _tf_ssb_following_after_work);
if (r)
{
_tf_ssb_following_after_work(&following->work, r);
}
return result;
}
void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
{
JS_NewClassID(&_tf_ssb_classId);
@ -1555,6 +1645,7 @@ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
JS_SetPropertyStr(context, object, "getBroadcasts", JS_NewCFunction(context, _tf_ssb_getBroadcasts, "getBroadcasts", 0));
JS_SetPropertyStr(context, object, "connect", JS_NewCFunction(context, _tf_ssb_connect, "connect", 1));
JS_SetPropertyStr(context, object, "createTunnel", JS_NewCFunction(context, _tf_ssb_createTunnel, "createTunnel", 3));
JS_SetPropertyStr(context, object, "following", JS_NewCFunction(context, _tf_ssb_following, "following", 2));
/* Write. */
JS_SetPropertyStr(context, object, "storeMessage", JS_NewCFunction(context, _tf_ssb_storeMessage, "storeMessage", 1));
JS_SetPropertyStr(context, object, "blobStore", JS_NewCFunction(context, _tf_ssb_blobStore, "blobStore", 1));