mirror of
https://github.com/status-im/realm-js.git
synced 2025-01-11 06:46:03 +00:00
RPC now keeps object keys in the same order
Maintaining insertion order when passing objects through the RPC is essential to make the new schema API work.
This commit is contained in:
parent
43e14093cc
commit
c928ab716e
@ -17,6 +17,7 @@ let propTypes = {};
|
|||||||
});
|
});
|
||||||
|
|
||||||
[
|
[
|
||||||
|
'DICT',
|
||||||
'FUNCTION',
|
'FUNCTION',
|
||||||
'REALM',
|
'REALM',
|
||||||
'RESULTS',
|
'RESULTS',
|
||||||
|
25
lib/rpc.js
25
lib/rpc.js
@ -10,6 +10,7 @@ const constants = require('./constants');
|
|||||||
const DEVICE_HOST = 'localhost:8082';
|
const DEVICE_HOST = 'localhost:8082';
|
||||||
|
|
||||||
const {keys, objectTypes, propTypes} = constants;
|
const {keys, objectTypes, propTypes} = constants;
|
||||||
|
const {id: idKey, realm: realmKey} = keys;
|
||||||
const typeConverters = {};
|
const typeConverters = {};
|
||||||
|
|
||||||
let XMLHttpRequest = global.originalXMLHttpRequest || global.XMLHttpRequest;
|
let XMLHttpRequest = global.originalXMLHttpRequest || global.XMLHttpRequest;
|
||||||
@ -40,6 +41,7 @@ module.exports = {
|
|||||||
|
|
||||||
registerTypeConverter(propTypes.DATA, (_, {value}) => base64.decode(value));
|
registerTypeConverter(propTypes.DATA, (_, {value}) => base64.decode(value));
|
||||||
registerTypeConverter(propTypes.DATE, (_, {value}) => new Date(value));
|
registerTypeConverter(propTypes.DATE, (_, {value}) => new Date(value));
|
||||||
|
registerTypeConverter(objectTypes.DICT, deserializeDict);
|
||||||
|
|
||||||
function registerTypeConverter(type, handler) {
|
function registerTypeConverter(type, handler) {
|
||||||
typeConverters[type] = handler;
|
typeConverters[type] = handler;
|
||||||
@ -106,9 +108,9 @@ function serialize(realmId, value) {
|
|||||||
return {value: value};
|
return {value: value};
|
||||||
}
|
}
|
||||||
|
|
||||||
let id = value[keys.id];
|
let id = value[idKey];
|
||||||
if (id) {
|
if (id) {
|
||||||
if (value[keys.realm] != realmId) {
|
if (value[realmKey] != realmId) {
|
||||||
throw new Error('Unable to serialize value from another Realm');
|
throw new Error('Unable to serialize value from another Realm');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,11 +130,9 @@ function serialize(realmId, value) {
|
|||||||
return {type: propTypes.DATA, value: base64.encode(value)};
|
return {type: propTypes.DATA, value: base64.encode(value)};
|
||||||
}
|
}
|
||||||
|
|
||||||
let object = {};
|
let keys = Object.keys(value);
|
||||||
for (let key in value) {
|
let values = keys.map((key) => serialize(realmId, value[key]));
|
||||||
object[key] = serialize(realmId, value[key]);
|
return {type: objectTypes.DICT, keys, values};
|
||||||
}
|
|
||||||
return {value: object};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function deserialize(realmId, info) {
|
function deserialize(realmId, info) {
|
||||||
@ -150,6 +150,17 @@ function deserialize(realmId, info) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deserializeDict(realmId, info) {
|
||||||
|
let {keys, values} = info;
|
||||||
|
let object = {};
|
||||||
|
|
||||||
|
for (let i = 0, len = keys.length; i < len; i++) {
|
||||||
|
object[keys[i]] = values[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
function sendRequest(command, data) {
|
function sendRequest(command, data) {
|
||||||
data = Object.assign({}, data, sessionId ? {sessionId} : null);
|
data = Object.assign({}, data, sessionId ? {sessionId} : null);
|
||||||
|
|
||||||
|
53
src/rpc.cpp
53
src/rpc.cpp
@ -22,6 +22,7 @@
|
|||||||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||||
using namespace realm_js;
|
using namespace realm_js;
|
||||||
|
|
||||||
|
static const char * const RealmObjectTypesDictionary = "ObjectTypesDICT";
|
||||||
static const char * const RealmObjectTypesFunction = "ObjectTypesFUNCTION";
|
static const char * const RealmObjectTypesFunction = "ObjectTypesFUNCTION";
|
||||||
static const char * const RealmObjectTypesResults = "ObjectTypesRESULTS";
|
static const char * const RealmObjectTypesResults = "ObjectTypesRESULTS";
|
||||||
|
|
||||||
@ -262,6 +263,28 @@ json RPCServer::serialize_json_value(JSValueRef value) {
|
|||||||
{"value", RJSValidatedValueToNumber(m_context, value)},
|
{"value", RJSValidatedValueToNumber(m_context, value)},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
JSPropertyNameArrayRef js_keys = JSObjectCopyPropertyNames(m_context, js_object);
|
||||||
|
size_t count = JSPropertyNameArrayGetCount(js_keys);
|
||||||
|
std::vector<std::string> keys;
|
||||||
|
std::vector<json> values;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
JSStringRef js_key = JSPropertyNameArrayGetNameAtIndex(js_keys, i);
|
||||||
|
JSValueRef js_value = RJSValidatedPropertyValue(m_context, js_object, js_key);
|
||||||
|
|
||||||
|
keys.push_back(RJSStringForJSString(js_key));
|
||||||
|
values.push_back(serialize_json_value(js_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
JSPropertyNameArrayRelease(js_keys);
|
||||||
|
|
||||||
|
return {
|
||||||
|
{"type", RealmObjectTypesDictionary},
|
||||||
|
{"keys", keys},
|
||||||
|
{"values", values},
|
||||||
|
};
|
||||||
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,6 +322,22 @@ JSValueRef RPCServer::deserialize_json_value(const json dict)
|
|||||||
|
|
||||||
return js_function;
|
return js_function;
|
||||||
}
|
}
|
||||||
|
else if (type_string == RealmObjectTypesDictionary) {
|
||||||
|
JSObjectRef js_object = JSObjectMake(m_context, NULL, NULL);
|
||||||
|
json keys = dict["keys"];
|
||||||
|
json values = dict["values"];
|
||||||
|
size_t count = keys.size();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
JSStringRef js_key = RJSStringForString(keys.at(i));
|
||||||
|
JSValueRef js_value = deserialize_json_value(values.at(i));
|
||||||
|
|
||||||
|
JSObjectSetProperty(m_context, js_object, js_key, js_value, 0, NULL);
|
||||||
|
JSStringRelease(js_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return js_object;
|
||||||
|
}
|
||||||
else if (type_string == RJSTypeGet(realm::PropertyTypeData)) {
|
else if (type_string == RJSTypeGet(realm::PropertyTypeData)) {
|
||||||
std::string bytes;
|
std::string bytes;
|
||||||
if (!base64_decode(value.get<std::string>(), &bytes)) {
|
if (!base64_decode(value.get<std::string>(), &bytes)) {
|
||||||
@ -344,19 +383,5 @@ JSValueRef RPCServer::deserialize_json_value(const json dict)
|
|||||||
|
|
||||||
return JSObjectMakeArray(m_context, count, js_values, NULL);
|
return JSObjectMakeArray(m_context, count, js_values, NULL);
|
||||||
}
|
}
|
||||||
else if (value.is_object()) {
|
|
||||||
JSObjectRef js_object = JSObjectMake(m_context, NULL, NULL);
|
|
||||||
|
|
||||||
for (json::iterator it = value.begin(); it != value.end(); ++it) {
|
|
||||||
JSValueRef js_value = deserialize_json_value(it.value());
|
|
||||||
JSStringRef js_key = JSStringCreateWithUTF8CString(it.key().c_str());
|
|
||||||
|
|
||||||
JSObjectSetProperty(m_context, js_object, js_key, js_value, 0, NULL);
|
|
||||||
JSStringRelease(js_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return js_object;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user