diff --git a/src/ssb.js.c b/src/ssb.js.c index eed53aec..6f3c9836 100644 --- a/src/ssb.js.c +++ b/src/ssb.js.c @@ -224,31 +224,71 @@ static JSValue _tf_ssb_set_server_following_me(JSContext* context, JSValueConst typedef struct _identities_visit_t { JSContext* context; - JSValue array; + JSValue promise[2]; + const char** identities; int count; + char user[]; } identities_visit_t; -static void _tf_ssb_getIdentities_visit(const char* identity, void* data) +static void _tf_ssb_getIdentities_visit(const char* identity, void* user_data) { - identities_visit_t* state = data; + identities_visit_t* work = user_data; + work->identities = tf_resize_vec(work->identities, (work->count + 1) * sizeof(const char*)); char id[k_id_base64_len]; snprintf(id, sizeof(id), "@%s", identity); - JS_SetPropertyUint32(state->context, state->array, state->count++, JS_NewString(state->context, id)); + work->identities[work->count++] = tf_strdup(id); +} + +static void _tf_ssb_get_identities_work(tf_ssb_t* ssb, void* user_data) +{ + identities_visit_t* work = user_data; + tf_ssb_db_identity_visit(ssb, work->user, _tf_ssb_getIdentities_visit, user_data); +} + +static void _tf_ssb_get_all_identities_work(tf_ssb_t* ssb, void* user_data) +{ + tf_ssb_db_identity_visit_all(ssb, _tf_ssb_getIdentities_visit, user_data); +} + +static void _tf_ssb_get_identities_after_work(tf_ssb_t* ssb, int status, void* user_data) +{ + identities_visit_t* work = user_data; + JSContext* context = tf_ssb_get_context(ssb); + JSValue result = JS_NewArray(context); + for (int i = 0; i < work->count; i++) + { + JS_SetPropertyUint32(context, result, i, JS_NewString(context, work->identities[i])); + tf_free((void*)work->identities[i]); + } + tf_free(work->identities); + + JSValue error = JS_Call(context, work->promise[0], JS_UNDEFINED, 1, &result); + JS_FreeValue(context, result); + tf_util_report_error(context, error); + JS_FreeValue(context, error); + JS_FreeValue(context, work->promise[0]); + JS_FreeValue(context, work->promise[1]); + tf_free(work); } static JSValue _tf_ssb_getIdentities(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { - JSValue result = JS_NewArray(context); + JSValue result = JS_UNDEFINED; tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); if (ssb) { - const char* user = JS_ToCString(context, argv[0]); - identities_visit_t state = { + size_t user_length = 0; + const char* user = JS_ToCStringLen(context, &user_length, argv[0]); + identities_visit_t* work = tf_malloc(sizeof(identities_visit_t) + user_length + 1); + *work = (identities_visit_t) + { .context = context, - .array = result, }; - tf_ssb_db_identity_visit(ssb, user, _tf_ssb_getIdentities_visit, &state); + memcpy(work->user, user, user_length + 1); JS_FreeCString(context, user); + + result = JS_NewPromiseCapability(context, work->promise); + tf_ssb_run_work(ssb, _tf_ssb_get_identities_work, _tf_ssb_get_identities_after_work, work); } return result; } @@ -286,15 +326,18 @@ static JSValue _tf_ssb_getServerIdentity(JSContext* context, JSValueConst this_v static JSValue _tf_ssb_getAllIdentities(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { - JSValue result = JS_NewArray(context); + JSValue result = JS_UNDEFINED; tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId); if (ssb) { - identities_visit_t state = { + identities_visit_t* work = tf_malloc(sizeof(identities_visit_t)); + *work = (identities_visit_t) + { .context = context, - .array = result, }; - tf_ssb_db_identity_visit_all(ssb, _tf_ssb_getIdentities_visit, &state); + + result = JS_NewPromiseCapability(context, work->promise); + tf_ssb_run_work(ssb, _tf_ssb_get_all_identities_work, _tf_ssb_get_identities_after_work, work); } return result; }