diff --git a/lib/results.js b/lib/results.js index ca22aabb..8154f6f6 100644 --- a/lib/results.js +++ b/lib/results.js @@ -6,11 +6,29 @@ let util = require('./util'); let idKey = util.idKey; let realmKey = util.realmKey; let resizeListKey = util.resizeListKey; +let prototype = {}; exports.create = create; +[ + 'sortByProperty', +].forEach(function(name) { + Object.defineProperty(prototype, name, { + value: function() { + let resultsId = this[idKey]; + let realmId = this[realmKey]; + + if (!resultsId || !realmId) { + throw new TypeError(name + ' method was not called on Results!'); + } + + return rpc.callListMethod(realmId, resultsId, name, Array.from(arguments)); + } + }); +}); + function create(realmId, info) { - let results = util.createList(null, getterForLength, getterForIndex); + let results = util.createList(prototype, getterForLength, getterForIndex); let size = info.size; results[realmKey] = realmId; diff --git a/lib/rpc.js b/lib/rpc.js index c91c8f49..d567dc42 100644 --- a/lib/rpc.js +++ b/lib/rpc.js @@ -17,27 +17,30 @@ if (XMLHttpRequest.__proto__ != window.XMLHttpRequestEventTarget) { window.XMLHttpRequest = override; } -exports.registerTypeConverter = registerTypeConverter; +module.exports = { + registerTypeConverter, -exports.createRealm = createRealm; -exports.callRealmMethod = callRealmMethod; + createRealm, + callRealmMethod, -exports.getObjectProperty = getObjectProperty; -exports.setObjectProperty = setObjectProperty; + getObjectProperty, + setObjectProperty, -exports.getListItem = getListItem; -exports.setListItem = setListItem; -exports.getListSize = getListSize; -exports.callListMethod = callListMethod; + getListItem, + setListItem, + getListSize, + callListMethod, -exports.getResultsItem = getResultsItem; -exports.getResultsSize = getResultsSize; + getResultsItem, + getResultsSize, + callResultsMethod, -exports.beginTransaction = beginTransaction; -exports.cancelTransaction = cancelTransaction; -exports.commitTransaction = commitTransaction; + beginTransaction, + cancelTransaction, + commitTransaction, -exports.clearTestState = clearTestState; + clearTestState, +}; function registerTypeConverter(type, handler) { typeConverters[type] = handler; @@ -101,6 +104,15 @@ function getResultsSize(realmId, resultsId) { return sendRequest('get_results_size', {realmId, resultsId}); } +function callResultsMethod(realmId, resultsId, name, args) { + if (args) { + args = args.map((arg) => serialize(realmId, arg)); + } + + let result = sendRequest('call_results_method', {realmId, resultsId, name, arguments: args}); + return deserialize(realmId, result); +} + function beginTransaction(realmId) { sendRequest('begin_transaction', {realmId}); } diff --git a/src/RJSResults.hpp b/src/RJSResults.hpp index 5ffb0d24..62996604 100644 --- a/src/RJSResults.hpp +++ b/src/RJSResults.hpp @@ -23,6 +23,7 @@ namespace realm { typedef std::shared_ptr SharedRealm; } +extern const JSStaticFunction RJSResultsFuncs[]; JSClassRef RJSResultsClass(); JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, std::string className); JSObjectRef RJSResultsCreate(JSContextRef ctx, realm::SharedRealm realm, std::string className, std::string query); diff --git a/src/RJSResults.mm b/src/RJSResults.mm index 594d48de..1ed15eab 100644 --- a/src/RJSResults.mm +++ b/src/RJSResults.mm @@ -118,12 +118,12 @@ JSObjectRef RJSResultsCreate(JSContextRef ctx, SharedRealm realm, std::string cl return RJSWrapObject(ctx, RJSResultsClass(), new Results(realm, *object_schema, std::move(query))); } +const JSStaticFunction RJSResultsFuncs[] = { + {"sortByProperty", SortByProperty, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, + {NULL, NULL}, +}; JSClassRef RJSResultsClass() { - const JSStaticFunction resultsFuncs[] = { - {"sortByProperty", SortByProperty, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete}, - {NULL, NULL}, - }; - static JSClassRef s_objectClass = RJSCreateWrapperClass("Results", ResultsGetProperty, NULL, resultsFuncs, ResultsPropertyNames); + static JSClassRef s_objectClass = RJSCreateWrapperClass("Results", ResultsGetProperty, NULL, RJSResultsFuncs, ResultsPropertyNames); return s_objectClass; } diff --git a/src/RealmRPC.mm b/src/RealmRPC.mm index cc357751..53161a33 100644 --- a/src/RealmRPC.mm +++ b/src/RealmRPC.mm @@ -169,6 +169,13 @@ using RPCRequest = std::function; } return @{@"result": @(length)}; }; + _requests["/call_results_method"] = [=](NSDictionary *dict) { + NSString *name = dict[@"name"]; + return [self performObjectMethod:name.UTF8String + classMethods:RJSResultsFuncs + args:dict[@"arguments"] + objectId:[dict[@"resultsId"] unsignedLongValue]]; + }; _requests["/get_list_item"] = [=](NSDictionary *dict) { RPCObjectID listId = [dict[@"listId"] unsignedLongValue]; long index = [dict[@"index"] longValue];