First glimpse of multiple SSB identities per Tilde Friends user.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3941 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
0bd1463a6b
commit
24530e1158
@ -1 +1 @@
|
||||
{"type":"tildefriends-app","files":{"app.js":"&TOlRdlgclkUtDVAOmfSoAQCoRzzMN4wAvKmF0cRvOHk=.sha256","index.html":"&TGAqOmpnOigx4XQbFix82ugZEOfR1Gdc2zMWUQMSvwI=.sha256","vue-material.js":"&K5cdLqXYCENPak/TCINHQhyJhpS4G9DlZHGwoh/LF2g=.sha256","tf-user.js":"&smJOHGgIsKwQXeEJD3VbHX4A+vhr1Se54WlSHUP/Km8=.sha256","tf-message.js":"&7M+IUC+xHyc306xRrJcx3TnYpONYLlgCsF80m2M2ws4=.sha256","tf.js":"&0+ub/dNZzf74GUWyVIzGZPb6pKJDx6y7I4Stsosh9Y0=.sha256","commonmark.min.js":"&EP0OeR9zyLwZannz+0ga4s9AGES2RLvvIIQYHqqV6+k=.sha256","vue.js":"&g1wvA+yHl1sVC+eufTsg9If7ZeVyMTBU+h0tks7ZNzE=.sha256","vue-material-theme-default-dark.css":"&RP2nr+2CR18BpHHw5ST9a5GJUCOG9n0G2kuGkcQioWE=.sha256","vue-material.min.css":"&kGbUM2QgFSyHZRzqQb0b+0S3EVIlZ0AXpdiAVjIhou8=.sha256","roboto.css":"&jJv43Om673mQO5JK0jj7714s5E+5Yrf82H6LcDx7wUs=.sha256","material-icons.css":"&a28PdcVvgq/DxyIvJAx/e+ZOEtOuHnr3kjLWKyzH11M=.sha256","tf-shared.js":"&MPINm55jkpz2rrNbwsYl09PKGvbgL3nwgBy6CMQkSnw=.sha256","style.css":"&qegBNCrVUihxffRUxGFuG/6u+0Y6d18zHtfNHBZtZ04=.sha256"}}
|
||||
{"type":"tildefriends-app","files":{"app.js":"&acYxT0G3CMw7yeOLrSZEyUMddadjz3Tj3s922ufQBcQ=.sha256","index.html":"&zWXxIB5f290SW1LGSasi41hNMJUwWzFTnSGeO/lh5zI=.sha256","vue-material.js":"&K5cdLqXYCENPak/TCINHQhyJhpS4G9DlZHGwoh/LF2g=.sha256","tf-user.js":"&smJOHGgIsKwQXeEJD3VbHX4A+vhr1Se54WlSHUP/Km8=.sha256","tf-message.js":"&7M+IUC+xHyc306xRrJcx3TnYpONYLlgCsF80m2M2ws4=.sha256","tf.js":"&FD0n9f4JMrvTFTxNOpMKDPv0e2Cex49G+oWdZOUcd/I=.sha256","commonmark.min.js":"&EP0OeR9zyLwZannz+0ga4s9AGES2RLvvIIQYHqqV6+k=.sha256","vue.js":"&g1wvA+yHl1sVC+eufTsg9If7ZeVyMTBU+h0tks7ZNzE=.sha256","vue-material-theme-default-dark.css":"&RP2nr+2CR18BpHHw5ST9a5GJUCOG9n0G2kuGkcQioWE=.sha256","vue-material.min.css":"&kGbUM2QgFSyHZRzqQb0b+0S3EVIlZ0AXpdiAVjIhou8=.sha256","roboto.css":"&jJv43Om673mQO5JK0jj7714s5E+5Yrf82H6LcDx7wUs=.sha256","material-icons.css":"&a28PdcVvgq/DxyIvJAx/e+ZOEtOuHnr3kjLWKyzH11M=.sha256","tf-shared.js":"&MPINm55jkpz2rrNbwsYl09PKGvbgL3nwgBy6CMQkSnw=.sha256","style.css":"&qegBNCrVUihxffRUxGFuG/6u+0Y6d18zHtfNHBZtZ04=.sha256"}}
|
@ -5,6 +5,8 @@ const k_votes_max = 20;
|
||||
|
||||
var g_ready = false;
|
||||
var g_selected = null;
|
||||
let g_whoami = null;
|
||||
let g_hash = null;
|
||||
|
||||
var g_blocking_cache = {};
|
||||
var g_following_cache = {};
|
||||
@ -313,7 +315,6 @@ async function getRelatedPostIds(db, message, ids, limit) {
|
||||
id = JSON.parse(message.content).root || id;
|
||||
} catch {
|
||||
}
|
||||
print("id = ", id);
|
||||
for (var i = 0; i < ids.length; i += k_batch_max) {
|
||||
var ids_batch = ids.slice(i, Math.min(i + k_batch_max, ids.length));
|
||||
await ssb.sqlStream(
|
||||
@ -395,8 +396,9 @@ async function getPosts(db, ids) {
|
||||
}
|
||||
|
||||
tfrpc.register(async function ready() {
|
||||
let identities = await ssb.getIdentities();
|
||||
await tfrpc.rpc.set_identities(identities);
|
||||
g_ready = true;
|
||||
return refresh(g_selected);
|
||||
});
|
||||
|
||||
tfrpc.register(async function store_blob(blob) {
|
||||
@ -439,13 +441,24 @@ async function updateSequences(db) {
|
||||
return changes;
|
||||
}
|
||||
|
||||
async function refresh(selected) {
|
||||
let g_refresh_limit = 5;
|
||||
|
||||
async function refresh_internal(whoami, selected) {
|
||||
if (typeof(whoami) !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (whoami !== g_whoami || selected !== g_selected) {
|
||||
g_whoami = whoami;
|
||||
g_selected = selected;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
var timing = [];
|
||||
timing.push({name: 'start', time: new Date()});
|
||||
g_following_cache = {};
|
||||
g_following_deep_cache = {};
|
||||
await tfrpc.rpc.clear();
|
||||
var whoami = await ssb.whoami();
|
||||
await tfrpc.rpc.set_identities(await ssb.getIdentities());
|
||||
var db = await database("ssb");
|
||||
g_sequence = {};
|
||||
try {
|
||||
@ -458,14 +471,15 @@ async function refresh(selected) {
|
||||
timing.push({name: 'blocked', time: new Date()});
|
||||
var all_followed = await followingDeep(db, [whoami], 2, blocked);
|
||||
timing.push({name: 'all_followed', time: new Date()});
|
||||
if (selected) {
|
||||
g_selected = selected;
|
||||
} else {
|
||||
g_selected = all_followed;
|
||||
let actual_selected = selected ? selected : all_followed;
|
||||
let hash = selected && selected.length == 1 ? selected[0] : null;
|
||||
if (hash !== g_hash) {
|
||||
g_hash = hash;
|
||||
print(g_hash, '=>', hash);
|
||||
//await tfrpc.rpc.set_hash(hash);
|
||||
}
|
||||
await Promise.all([
|
||||
tfrpc.rpc.set('whoami', whoami),,
|
||||
tfrpc.rpc.set_hash(selected && selected.length == 1 ? selected[0] : null),
|
||||
tfrpc.rpc.set('whoami', whoami),
|
||||
tfrpc.rpc.set('broadcasts', await ssb.getBroadcasts()),
|
||||
tfrpc.rpc.set('connections', await ssb.connections()),
|
||||
tfrpc.rpc.set('apps', await core.apps()),
|
||||
@ -477,7 +491,7 @@ async function refresh(selected) {
|
||||
m = m.length ? m[0] : {id: selected[0]};
|
||||
ids = await getRelatedPostIds(db, m, all_followed, k_posts_max);
|
||||
} else {
|
||||
ids = await getRecentPostIds2(db, whoami, g_selected, (new Date()).valueOf() - (24 * 60 * 60 * 1000));
|
||||
ids = await getRecentPostIds2(db, whoami, actual_selected, (new Date()).valueOf() - (24 * 60 * 60 * 1000));
|
||||
}
|
||||
timing.push({name: 'get_post_ids', time: new Date()});
|
||||
var posts = await getPosts(db, ids);
|
||||
@ -544,7 +558,7 @@ ssb.addEventListener('message', async function(id) {
|
||||
var db = await database("ssb");
|
||||
var posts = await getPosts(db, [id]);
|
||||
for (let post of posts) {
|
||||
if (post.author == await ssb.whoami() ||
|
||||
if (post.author == g_whoami ||
|
||||
JSON.parse(post.content).type != 'post') {
|
||||
await tfrpc.rpc.push_posts([post]);
|
||||
} else {
|
||||
@ -553,6 +567,10 @@ ssb.addEventListener('message', async function(id) {
|
||||
}
|
||||
});
|
||||
|
||||
tfrpc.register(async function refresh(whoami, selected) {
|
||||
return refresh_internal(whoami, selected);
|
||||
});
|
||||
|
||||
async function addAppSources(message) {
|
||||
if (message.mentions) {
|
||||
for (let mention of message.mentions) {
|
||||
@ -576,19 +594,11 @@ core.register('message', async function(m) {
|
||||
await ssb.connect(m.message.connect);
|
||||
} else if (m.message.appendMessage) {
|
||||
await addAppSources(m.message.appendMessage);
|
||||
await ssb.appendMessage(m.message.appendMessage);
|
||||
} else if (m.message.refresh) {
|
||||
await refresh(g_selected);
|
||||
await ssb.appendMessageWithIdentity(g_whoami, m.message.appendMessage);
|
||||
}
|
||||
} else if (m.event == 'hashChange') {
|
||||
if (m.hash.length > 1) {
|
||||
g_selected = [m.hash.substring(1)];
|
||||
} else {
|
||||
g_selected = null;
|
||||
}
|
||||
if (g_ready) {
|
||||
await refresh(g_selected);
|
||||
}
|
||||
let selected = m.hash.length > 1 ? [m.hash.substring(1)] : null;
|
||||
await refresh_internal(g_whoami, selected);
|
||||
} else if (m.event == 'focus' || m.event == 'blur') {
|
||||
/* Shh. */
|
||||
} else {
|
||||
|
@ -43,7 +43,13 @@
|
||||
</md-app-toolbar>
|
||||
<md-app class="md-elevation-8">
|
||||
<md-app-toolbar>
|
||||
<div>Welcome, <tf-user :id="whoami"></tf-user>.</div>
|
||||
<div>Welcome, <tf-user :id="whoami"></tf-user>
|
||||
<md-field>
|
||||
<md-select v-model="whoami" name="whoami" id="whoami" :change="refresh()">
|
||||
<md-option v-for="identity in identities" v-bind:key="identity" :value="identity">{{identity}}</md-option>
|
||||
</md-select>
|
||||
</md-field>
|
||||
</div>
|
||||
</md-app-toolbar>
|
||||
<md-app-content>
|
||||
<span v-if="load_time">
|
||||
|
@ -3,6 +3,7 @@ import * as tfshared from './tf-shared.js';
|
||||
|
||||
export var g_data = {
|
||||
whoami: null,
|
||||
identities: [],
|
||||
connections: [],
|
||||
messages: [],
|
||||
messages_by_id: {},
|
||||
@ -48,7 +49,9 @@ tfrpc.register(function clear() {
|
||||
g_load_start = new Date();
|
||||
g_data.loading = true;
|
||||
Object.keys(g_data_initial).forEach(function(key) {
|
||||
Vue.set(g_data, key, JSON.parse(JSON.stringify(g_data_initial[key])));
|
||||
if (key != 'identities' && key != 'whoami') {
|
||||
Vue.set(g_data, key, JSON.parse(JSON.stringify(g_data_initial[key])));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -56,6 +59,15 @@ tfrpc.register(function set(key, value) {
|
||||
g_data[key] = value;
|
||||
});
|
||||
|
||||
tfrpc.register(function set_identities(value) {
|
||||
if (JSON.stringify(g_data.identities) != JSON.stringify(value)) {
|
||||
g_data.identities = value.map(x => x);
|
||||
}
|
||||
if (!g_data.whoami && value.length) {
|
||||
g_data.whoami = value[0];
|
||||
}
|
||||
});
|
||||
|
||||
tfrpc.register(function push_users(users) {
|
||||
for (let [id, user] of Object.entries(users)) {
|
||||
Vue.set(g_data.users, id, Object.assign({}, g_data.users[id] || {}, user));
|
||||
@ -207,7 +219,7 @@ window.addEventListener('load', function() {
|
||||
},
|
||||
markdown: tfshared.markdown,
|
||||
refresh: function() {
|
||||
window.parent.postMessage({refresh: true}, '*');
|
||||
tfrpc.rpc.refresh(g_data.whoami);
|
||||
},
|
||||
add_app_to_mentions: function(app) {
|
||||
Vue.set(g_data.mentions, g_data.apps[app], {
|
||||
|
@ -249,6 +249,13 @@ async function getProcessBlob(blobId, key, options) {
|
||||
return ssb.getIdentities(process.credentials.session.name);
|
||||
}
|
||||
};
|
||||
imports.ssb.appendMessageWithIdentity = function(id, message) {
|
||||
if (process.credentials &&
|
||||
process.credentials.session &&
|
||||
process.credentials.session.name) {
|
||||
return ssb.appendMessageWithIdentity(process.credentials.session.name, id, message);
|
||||
}
|
||||
};
|
||||
if (process.credentials &&
|
||||
process.credentials.session &&
|
||||
process.credentials.session.name) {
|
||||
|
16
core/ssb.js
16
core/ssb.js
@ -77,10 +77,10 @@ ssb.addEventListener('connections', function(change, connection) {
|
||||
var sequence = get_latest_sequence_for_author(connection.id);
|
||||
if (k_use_create_history_stream) {
|
||||
connection.send_json({'name': ['createHistoryStream'], 'type': 'source', 'args': [{'id': connection.id, 'seq': sequence, 'live': true, 'keys': false}]}, storeMessage);
|
||||
var me = ssb.whoami();
|
||||
followingDeep(g_database, [me], 2).then(function(ids) {
|
||||
var identities = ssb.getAllIdentities();
|
||||
followingDeep(g_database, identities, 2).then(function(ids) {
|
||||
for (let id of ids) {
|
||||
if (id == me) {
|
||||
if (identities.indexOf(id) != -1) {
|
||||
continue;
|
||||
}
|
||||
var sequence = get_latest_sequence_for_author(id);
|
||||
@ -201,10 +201,10 @@ ssb.addRpc(['tunnel', 'isRoom'], function(request) {
|
||||
});
|
||||
|
||||
function ebtReplicateSendClock(request, have) {
|
||||
var me = ssb.whoami();
|
||||
var identities = ssb.getAllIdentities();
|
||||
var message = {};
|
||||
var last_sent = request.connection.sent_clock || {};
|
||||
var ids = followingDeep(g_database, [me], 2).concat([request.connection.id]);
|
||||
var ids = followingDeep(g_database, identities, 2).concat([request.connection.id]);
|
||||
if (!Object.keys(last_sent).length) {
|
||||
for (let id of ids) {
|
||||
message[id] = get_latest_sequence_for_author(id);
|
||||
@ -261,11 +261,10 @@ function formatMessage(row) {
|
||||
}
|
||||
|
||||
function ebtReplicateRegisterMessageCallback(request) {
|
||||
var me = ssb.whoami();
|
||||
ssb.addEventListener('message', function(message_id) {
|
||||
ssb.sqlStream(
|
||||
'SELECT previous, author, id, sequence, timestamp, hash, content, signature FROM messages WHERE id = ?1 AND author = ?2',
|
||||
[message_id, me],
|
||||
'SELECT previous, author, id, sequence, timestamp, hash, content, signature FROM messages WHERE id = ?1',
|
||||
[message_id],
|
||||
function (row) {
|
||||
request.send_json(formatMessage(row));
|
||||
});
|
||||
@ -273,7 +272,6 @@ function ebtReplicateRegisterMessageCallback(request) {
|
||||
}
|
||||
|
||||
function ebtReplicateCommon(request) {
|
||||
var me = ssb.whoami();
|
||||
if (request.message.author) {
|
||||
storeMessage(request);
|
||||
} else {
|
||||
|
14
src/ssb.db.c
14
src/ssb.db.c
@ -759,6 +759,20 @@ void tf_ssb_db_identity_visit(tf_ssb_t* ssb, const char* user, void (*callback)(
|
||||
}
|
||||
}
|
||||
|
||||
void tf_ssb_db_identity_visit_all(tf_ssb_t* ssb, void (*callback)(const char* identity, void* user_data), void* user_data)
|
||||
{
|
||||
sqlite3* db = tf_ssb_get_db(ssb);
|
||||
sqlite3_stmt* statement = NULL;
|
||||
if (sqlite3_prepare(db, "SELECT public_key FROM identities ORDER BY public_key", -1, &statement, NULL) == SQLITE_OK)
|
||||
{
|
||||
while (sqlite3_step(statement) == SQLITE_ROW)
|
||||
{
|
||||
callback((const char*)sqlite3_column_text(statement, 0), user_data);
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
}
|
||||
|
||||
bool tf_ssb_db_identity_get_private_key(tf_ssb_t* ssb, const char* user, const char* public_key, uint8_t* out_private_key, size_t private_key_size)
|
||||
{
|
||||
bool success = false;
|
||||
|
@ -21,4 +21,5 @@ bool tf_ssb_db_check(sqlite3* db, const char* author);
|
||||
int tf_ssb_db_identity_get_count_for_user(tf_ssb_t* ssb, const char* user);
|
||||
bool tf_ssb_db_identity_add(tf_ssb_t* ssb, const char* user, const char* public_key, const char* private_key);
|
||||
void tf_ssb_db_identity_visit(tf_ssb_t* ssb, const char* user, void (*callback)(const char* identity, void* user_data), void* user_data);
|
||||
void tf_ssb_db_identity_visit_all(tf_ssb_t* ssb, void (*callback)(const char* identity, void* user_data), void* user_data);
|
||||
bool tf_ssb_db_identity_get_private_key(tf_ssb_t* ssb, const char* user, const char* public_key, uint8_t* out_private_key, size_t private_key_size);
|
||||
|
68
src/ssb.js.c
68
src/ssb.js.c
@ -18,20 +18,6 @@ static JSClassID _tf_ssb_classId;
|
||||
|
||||
void _tf_ssb_on_rpc(tf_ssb_connection_t* connection, uint8_t flags, int32_t request_number, JSValue args, const uint8_t* message, size_t size, void* user_data);
|
||||
|
||||
static JSValue _tf_ssb_whoami(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
|
||||
if (ssb)
|
||||
{
|
||||
char id[512];
|
||||
if (tf_ssb_whoami(ssb, id, sizeof(id)))
|
||||
{
|
||||
return JS_NewString(context, id);
|
||||
}
|
||||
}
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_createIdentity(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
|
||||
@ -69,7 +55,9 @@ typedef struct _identities_visit_t
|
||||
static void _tf_ssb_getIdentities_visit(const char* identity, void* data)
|
||||
{
|
||||
identities_visit_t* state = data;
|
||||
JS_SetPropertyUint32(state->context, state->array, state->count++, JS_NewString(state->context, identity));
|
||||
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));
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_getIdentities(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
@ -90,6 +78,22 @@ static JSValue _tf_ssb_getIdentities(JSContext* context, JSValueConst this_val,
|
||||
return result;
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_getAllIdentities(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
JSValue result = JS_NewArray(context);
|
||||
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
|
||||
if (ssb)
|
||||
{
|
||||
identities_visit_t state =
|
||||
{
|
||||
.context = context,
|
||||
.array = result,
|
||||
};
|
||||
tf_ssb_db_identity_visit_all(ssb, _tf_ssb_getIdentities_visit, &state);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_appendMessageWithIdentity(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
JSValue result = JS_UNDEFINED;
|
||||
@ -277,31 +281,6 @@ static JSValue _tf_ssb_sqlStream(JSContext* context, JSValueConst this_val, int
|
||||
return result;
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_post(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
|
||||
if (ssb)
|
||||
{
|
||||
const char* post_text = JS_ToCString(context, argv[0]);
|
||||
if (post_text)
|
||||
{
|
||||
tf_ssb_append_post(ssb, post_text);
|
||||
JS_FreeCString(context, post_text);
|
||||
}
|
||||
}
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_appendMessage(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
|
||||
if (ssb)
|
||||
{
|
||||
tf_ssb_append_message(ssb, argv[0]);
|
||||
}
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
static JSValue _tf_ssb_storeMessage(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
tf_ssb_t* ssb = JS_GetOpaque(this_val, _tf_ssb_classId);
|
||||
@ -846,25 +825,26 @@ void tf_ssb_register(JSContext* context, tf_ssb_t* ssb)
|
||||
JSValue object = JS_NewObjectClass(context, _tf_ssb_classId);
|
||||
JS_SetPropertyStr(context, global, "ssb", object);
|
||||
JS_SetOpaque(object, ssb);
|
||||
|
||||
/* Requires an identity. */
|
||||
JS_SetPropertyStr(context, object, "createIdentity", JS_NewCFunction(context, _tf_ssb_createIdentity, "createIdentity", 1));
|
||||
JS_SetPropertyStr(context, object, "getIdentities", JS_NewCFunction(context, _tf_ssb_getIdentities, "getIdentities", 1));
|
||||
JS_SetPropertyStr(context, object, "appendMessageWithIdentity", JS_NewCFunction(context, _tf_ssb_appendMessageWithIdentity, "appendMessageWithIdentity", 3));
|
||||
|
||||
JS_SetPropertyStr(context, object, "whoami", JS_NewCFunction(context, _tf_ssb_whoami, "whoami", 0));
|
||||
/* Does not require an identity. */
|
||||
JS_SetPropertyStr(context, object, "getAllIdentities", JS_NewCFunction(context, _tf_ssb_getAllIdentities, "getAllIdentities", 0));
|
||||
JS_SetPropertyStr(context, object, "getMessage", JS_NewCFunction(context, _tf_ssb_getMessage, "getMessage", 2));
|
||||
JS_SetPropertyStr(context, object, "blobGet", JS_NewCFunction(context, _tf_ssb_blobGet, "blobGet", 1));
|
||||
JS_SetPropertyStr(context, object, "blobStore", JS_NewCFunction(context, _tf_ssb_blobStore, "blobStore", 2));
|
||||
JS_SetPropertyStr(context, object, "messageContentGet", JS_NewCFunction(context, _tf_ssb_messageContentGet, "messageContentGet", 1));
|
||||
JS_SetPropertyStr(context, object, "connections", JS_NewCFunction(context, _tf_ssb_connections, "connections", 0));
|
||||
JS_SetPropertyStr(context, object, "sqlStream", JS_NewCFunction(context, _tf_ssb_sqlStream, "sqlStream", 3));
|
||||
JS_SetPropertyStr(context, object, "post", JS_NewCFunction(context, _tf_ssb_post, "post", 1));
|
||||
JS_SetPropertyStr(context, object, "appendMessage", JS_NewCFunction(context, _tf_ssb_appendMessage, "appendMessage", 1));
|
||||
JS_SetPropertyStr(context, object, "storeMessage", JS_NewCFunction(context, _tf_ssb_storeMessage, "storeMessage", 1));
|
||||
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));
|
||||
|
||||
/* Should be trusted only. */
|
||||
JS_SetPropertyStr(context, object, "addRpc", JS_NewCFunction(context, _tf_ssb_add_rpc, "addRpc", 2));
|
||||
|
||||
JS_SetPropertyStr(context, object, "addEventListener", JS_NewCFunction(context, _tf_ssb_add_event_listener, "addEventListener", 2));
|
||||
JS_SetPropertyStr(context, object, "removeEventListener", JS_NewCFunction(context, _tf_ssb_remove_event_listener, "removeEventListener", 2));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user