diff --git a/lib/rpc.js b/lib/rpc.js index 89c13ab6..5b489085 100644 --- a/lib/rpc.js +++ b/lib/rpc.js @@ -76,7 +76,7 @@ function getListItem(realmId, listId, index) { } function setListItem(realmId, listId, index, value) { - sendRequest('set_list_item', {realmId, listId, index, value}); + sendRequest('set_list_item', {realmId, listId, index, value: serialize(realmId, value)}); } function getListSize(realmId, listId) { diff --git a/src/RJSList.hpp b/src/RJSList.hpp index 6dbe9dd0..aaa07571 100644 --- a/src/RJSList.hpp +++ b/src/RJSList.hpp @@ -25,3 +25,4 @@ JSClassRef RJSListClass(); JSObjectRef RJSListCreate(JSContextRef ctx, realm::List &list); JSValueRef ListGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException); +bool ListSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* jsException); \ No newline at end of file diff --git a/src/RealmRPC.mm b/src/RealmRPC.mm index 531e5f06..226ea192 100644 --- a/src/RealmRPC.mm +++ b/src/RealmRPC.mm @@ -52,7 +52,7 @@ using RPCRequest = std::function; JSValueRef argValues[argCount]; for (NSUInteger i = 0; i < argCount; i++) { - argValues[i] = [self valueFromDictionary:args[i]]; + argValues[i] = [self deserializeDictionaryValue:args[i]]; } JSValueRef exception = NULL; @@ -103,7 +103,7 @@ using RPCRequest = std::function; _requests["/set_property"] = [=](NSDictionary *dict) { JSStringRef propString = RJSStringForString([dict[@"name"] UTF8String]); RPCObjectID realmId = [dict[@"objectId"] unsignedLongValue]; - JSValueRef value = [self valueFromDictionary:dict[@"value"]]; + JSValueRef value = [self deserializeDictionaryValue:dict[@"value"]]; JSValueRef exception = NULL; ObjectSetProperty(_context, _objects[realmId], propString, value, &exception); @@ -172,6 +172,22 @@ using RPCRequest = std::function; return @{@"result": [self resultForJSValue:objectValue]}; }; + _requests["/set_list_item"] = [=](NSDictionary *dict) { + RPCObjectID listId = [dict[@"listId"] unsignedLongValue]; + long index = [dict[@"index"] longValue]; + + JSValueRef exception = NULL; + JSStringRef indexPropertyName = JSStringCreateWithUTF8CString(std::to_string(index).c_str()); + JSValueRef value = [self deserializeDictionaryValue:dict[@"value"]]; + ListSetProperty(_context, _objects[listId], indexPropertyName, value, &exception); + JSStringRelease(indexPropertyName); + + if (exception) { + return @{@"error": @(RJSStringForValue(_context, exception).c_str())}; + } + + return @{}; + }; _requests["/call_list_method"] = [=](NSDictionary *dict) { NSString *name = dict[@"name"]; return [self performObjectMethod:name.UTF8String @@ -190,6 +206,8 @@ using RPCRequest = std::function; - (NSDictionary *)performRequest:(NSString *)name args:(NSDictionary *)args { // perform all realm ops on the main thread RPCRequest action = _requests[name.UTF8String]; + assert(action); + __block id response; dispatch_sync(dispatch_get_main_queue(), ^{ try { @@ -208,7 +226,7 @@ using RPCRequest = std::function; NSUInteger argCount = args.count; JSValueRef argValues[argCount]; for (NSUInteger i = 0; i < argCount; i++) { - argValues[i] = [self valueFromDictionary:args[i]]; + argValues[i] = [self deserializeDictionaryValue:args[i]]; } size_t index = 0; @@ -313,7 +331,7 @@ using RPCRequest = std::function; }; } -- (JSValueRef)valueFromDictionary:(NSDictionary *)dict { +- (JSValueRef)deserializeDictionaryValue:(NSDictionary *)dict { RPCObjectID oid = [dict[@"id"] longValue]; if (oid) { return _objects[oid]; @@ -340,7 +358,7 @@ using RPCRequest = std::function; JSValueRef jsValues[count]; for (NSUInteger i = 0; i < count; i++) { - jsValues[i] = [self valueFromDictionary:value[i]]; + jsValues[i] = [self deserializeDictionaryValue:value[i]]; } return JSObjectMakeArray(_context, count, jsValues, NULL); @@ -349,7 +367,7 @@ using RPCRequest = std::function; JSObjectRef jsObject = JSObjectMake(_context, NULL, NULL); for (NSString *key in value) { - JSValueRef jsValue = [self valueFromDictionary:value[key]]; + JSValueRef jsValue = [self deserializeDictionaryValue:value[key]]; JSStringRef jsKey = JSStringCreateWithCFString((__bridge CFStringRef)key); JSObjectSetProperty(_context, jsObject, jsKey, jsValue, 0, NULL);