Merge pull request #41 from realm/al-rpc
Partial chrome support (enough for the example)
This commit is contained in:
commit
a670961b13
|
@ -93,3 +93,7 @@ build/
|
|||
|
||||
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
||||
.rvmrc
|
||||
|
||||
# node.js
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "vendor/GCDWebServer"]
|
||||
path = vendor/GCDWebServer
|
||||
url = https://github.com/swisspol/GCDWebServer.git
|
|
@ -17,8 +17,8 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "Base/RCTBridgeModule.h"
|
||||
@import RealmJS;
|
||||
|
||||
@protocol RCTBridgeModule;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#import "Base/RCTLog.h"
|
||||
#import "Base/RCTBridge.h"
|
||||
|
||||
@import GCDWebServers;
|
||||
@import RealmJS;
|
||||
@import JavaScriptCore;
|
||||
|
||||
|
@ -49,6 +50,29 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
// The executor could be a RCTWebSocketExecutor, in which case it won't have a JS context.
|
||||
if (!contextIvar) {
|
||||
|
||||
[GCDWebServer setLogLevel:3];
|
||||
GCDWebServer *webServer = [[GCDWebServer alloc] init];
|
||||
RJSRPCServer *rpcServer = [[RJSRPCServer alloc] init];
|
||||
|
||||
// Add a handler to respond to POST requests on any URL
|
||||
[webServer addDefaultHandlerForMethod:@"POST"
|
||||
requestClass:[GCDWebServerDataRequest class]
|
||||
processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {
|
||||
NSError *error;
|
||||
NSData *data = [(GCDWebServerDataRequest *)request data];
|
||||
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
|
||||
if (error) {
|
||||
NSLog(@"%@", error);
|
||||
return [GCDWebServerErrorResponse responseWithClientError:kGCDWebServerHTTPStatusCode_UnprocessableEntity underlyingError:error message:@"Invalid RPC request"];
|
||||
}
|
||||
|
||||
GCDWebServerDataResponse *response = [GCDWebServerDataResponse responseWithJSONObject:[rpcServer performRequest:request.path args:json]];
|
||||
[response setValue:@"http://localhost:8081" forAdditionalHeader:@"Access-Control-Allow-Origin"];
|
||||
return response;
|
||||
}];
|
||||
|
||||
[webServer startWithPort:8082 bonjourName:nil];
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
02258FB31BC6E2D00075F13A /* RealmRPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 02258FB11BC6E2D00075F13A /* RealmRPC.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
02258FB41BC6E2D00075F13A /* RealmRPC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 02258FB21BC6E2D00075F13A /* RealmRPC.mm */; settings = {ASSET_TAGS = (); }; };
|
||||
02601F031BA0F0C4007C91FF /* external_commit_helper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02601F011BA0F0C4007C91FF /* external_commit_helper.cpp */; };
|
||||
02601F041BA0F0C4007C91FF /* external_commit_helper.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 02601F021BA0F0C4007C91FF /* external_commit_helper.hpp */; };
|
||||
02601F081BA0F0CD007C91FF /* index_set.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02601F051BA0F0CD007C91FF /* index_set.cpp */; };
|
||||
|
@ -19,16 +21,16 @@
|
|||
0270BC4C1B7CFC0D00010E03 /* RealmJS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC3E1B7CFC0D00010E03 /* RealmJS.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
0270BC4D1B7CFC0D00010E03 /* RealmJS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC3F1B7CFC0D00010E03 /* RealmJS.mm */; };
|
||||
0270BC4E1B7CFC0D00010E03 /* RJSArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC401B7CFC0D00010E03 /* RJSArray.cpp */; };
|
||||
0270BC4F1B7CFC0D00010E03 /* RJSArray.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC411B7CFC0D00010E03 /* RJSArray.hpp */; };
|
||||
0270BC501B7CFC0D00010E03 /* RJSObject.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC421B7CFC0D00010E03 /* RJSObject.hpp */; };
|
||||
0270BC4F1B7CFC0D00010E03 /* RJSArray.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC411B7CFC0D00010E03 /* RJSArray.hpp */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
0270BC501B7CFC0D00010E03 /* RJSObject.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC421B7CFC0D00010E03 /* RJSObject.hpp */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
0270BC511B7CFC0D00010E03 /* RJSObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC431B7CFC0D00010E03 /* RJSObject.mm */; };
|
||||
0270BC521B7CFC0D00010E03 /* RJSRealm.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC441B7CFC0D00010E03 /* RJSRealm.hpp */; };
|
||||
0270BC521B7CFC0D00010E03 /* RJSRealm.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC441B7CFC0D00010E03 /* RJSRealm.hpp */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
0270BC531B7CFC0D00010E03 /* RJSRealm.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC451B7CFC0D00010E03 /* RJSRealm.mm */; };
|
||||
0270BC541B7CFC0D00010E03 /* RJSResults.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC461B7CFC0D00010E03 /* RJSResults.hpp */; };
|
||||
0270BC541B7CFC0D00010E03 /* RJSResults.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC461B7CFC0D00010E03 /* RJSResults.hpp */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
0270BC551B7CFC0D00010E03 /* RJSResults.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC471B7CFC0D00010E03 /* RJSResults.mm */; };
|
||||
0270BC561B7CFC0D00010E03 /* RJSSchema.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC481B7CFC0D00010E03 /* RJSSchema.hpp */; };
|
||||
0270BC561B7CFC0D00010E03 /* RJSSchema.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC481B7CFC0D00010E03 /* RJSSchema.hpp */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
0270BC571B7CFC0D00010E03 /* RJSSchema.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC491B7CFC0D00010E03 /* RJSSchema.mm */; };
|
||||
0270BC581B7CFC0D00010E03 /* RJSUtil.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC4A1B7CFC0D00010E03 /* RJSUtil.hpp */; };
|
||||
0270BC581B7CFC0D00010E03 /* RJSUtil.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC4A1B7CFC0D00010E03 /* RJSUtil.hpp */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
0270BC591B7CFC0D00010E03 /* RJSUtil.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC4B1B7CFC0D00010E03 /* RJSUtil.mm */; };
|
||||
0270BC671B7CFC1C00010E03 /* object_accessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0270BC5C1B7CFC1C00010E03 /* object_accessor.cpp */; };
|
||||
0270BC681B7CFC1C00010E03 /* object_accessor.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0270BC5D1B7CFC1C00010E03 /* object_accessor.hpp */; };
|
||||
|
@ -49,6 +51,7 @@
|
|||
0270BC861B7D020100010E03 /* TestObjects.js in Resources */ = {isa = PBXBuildFile; fileRef = 0270BC7F1B7D020100010E03 /* TestObjects.js */; };
|
||||
0270BC871B7D023200010E03 /* RealmJS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02B58CB11AE99CEC009B348C /* RealmJS.framework */; };
|
||||
0270BCD11B7D067300010E03 /* RealmReactModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 0270BCD01B7D067300010E03 /* RealmReactModule.m */; };
|
||||
02A3C7971BC4318600B1A7BE /* GCDWebServers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02A3C7941BC4317A00B1A7BE /* GCDWebServers.framework */; };
|
||||
02B29A311B7CF86D008A7E6B /* RealmJS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02B58CB11AE99CEC009B348C /* RealmJS.framework */; };
|
||||
02B58CCE1AE99D4D009B348C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 02B58CCD1AE99D4D009B348C /* JavaScriptCore.framework */; };
|
||||
02D456DA1B7E59A500EE1299 /* ArrayTests.js in Resources */ = {isa = PBXBuildFile; fileRef = 02D456D91B7E59A500EE1299 /* ArrayTests.js */; };
|
||||
|
@ -56,6 +59,41 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
02A3C78D1BC4317A00B1A7BE /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 02A3C7841BC4317A00B1A7BE /* GCDWebServer.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 8DD76FB20486AB0100D96B5E;
|
||||
remoteInfo = "GCDWebServer (Mac)";
|
||||
};
|
||||
02A3C78F1BC4317A00B1A7BE /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 02A3C7841BC4317A00B1A7BE /* GCDWebServer.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = E221125A1690B4DE0048D2B2;
|
||||
remoteInfo = "GCDWebServer (iOS)";
|
||||
};
|
||||
02A3C7911BC4317A00B1A7BE /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 02A3C7841BC4317A00B1A7BE /* GCDWebServer.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = CEE28CD11AE004D800F4023C;
|
||||
remoteInfo = "GCDWebServers (Mac)";
|
||||
};
|
||||
02A3C7931BC4317A00B1A7BE /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 02A3C7841BC4317A00B1A7BE /* GCDWebServer.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = CEE28CEF1AE0051F00F4023C;
|
||||
remoteInfo = "GCDWebServers (iOS)";
|
||||
};
|
||||
02A3C7951BC4317A00B1A7BE /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 02A3C7841BC4317A00B1A7BE /* GCDWebServer.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = E24039251BA09207000B7089;
|
||||
remoteInfo = "Tests (Mac)";
|
||||
};
|
||||
02B29A2F1B7CF7ED008A7E6B /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 02B58CA81AE99CEB009B348C /* Project object */;
|
||||
|
@ -85,6 +123,8 @@
|
|||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
02258FB11BC6E2D00075F13A /* RealmRPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RealmRPC.h; path = src/RealmRPC.h; sourceTree = "<group>"; };
|
||||
02258FB21BC6E2D00075F13A /* RealmRPC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RealmRPC.mm; path = src/RealmRPC.mm; sourceTree = "<group>"; };
|
||||
02601F011BA0F0C4007C91FF /* external_commit_helper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = external_commit_helper.cpp; path = "src/object-store/apple/external_commit_helper.cpp"; sourceTree = "<group>"; };
|
||||
02601F021BA0F0C4007C91FF /* external_commit_helper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = external_commit_helper.hpp; path = "src/object-store/apple/external_commit_helper.hpp"; sourceTree = "<group>"; };
|
||||
02601F051BA0F0CD007C91FF /* index_set.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = index_set.cpp; path = "src/object-store/index_set.cpp"; sourceTree = "<group>"; };
|
||||
|
@ -130,6 +170,8 @@
|
|||
0270BC7F1B7D020100010E03 /* TestObjects.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TestObjects.js; path = tests/TestObjects.js; sourceTree = SOURCE_ROOT; };
|
||||
0270BCCF1B7D067300010E03 /* RealmReactModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RealmReactModule.h; path = ReactNative/RealmReactModule.h; sourceTree = "<group>"; };
|
||||
0270BCD01B7D067300010E03 /* RealmReactModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RealmReactModule.m; path = ReactNative/RealmReactModule.m; sourceTree = "<group>"; };
|
||||
02A3C7841BC4317A00B1A7BE /* GCDWebServer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GCDWebServer.xcodeproj; path = vendor/GCDWebServer/GCDWebServer.xcodeproj; sourceTree = "<group>"; };
|
||||
02A3C7A41BC4341500B1A7BE /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
|
||||
02B29A161B7CF7C9008A7E6B /* libRealmReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRealmReact.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
02B58CB11AE99CEC009B348C /* RealmJS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RealmJS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
02B58CBC1AE99CEC009B348C /* RealmJSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RealmJSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -142,6 +184,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
02A3C7971BC4318600B1A7BE /* GCDWebServers.framework in Frameworks */,
|
||||
02B29A311B7CF86D008A7E6B /* RealmJS.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -191,6 +234,8 @@
|
|||
02601F071BA0F0CD007C91FF /* realm_delegate.hpp */,
|
||||
0270BC3E1B7CFC0D00010E03 /* RealmJS.h */,
|
||||
0270BC3F1B7CFC0D00010E03 /* RealmJS.mm */,
|
||||
02258FB11BC6E2D00075F13A /* RealmRPC.h */,
|
||||
02258FB21BC6E2D00075F13A /* RealmRPC.mm */,
|
||||
0270BC401B7CFC0D00010E03 /* RJSArray.cpp */,
|
||||
0270BC411B7CFC0D00010E03 /* RJSArray.hpp */,
|
||||
0270BC421B7CFC0D00010E03 /* RJSObject.hpp */,
|
||||
|
@ -217,9 +262,22 @@
|
|||
name = ReactNativeModule;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
02A3C7851BC4317A00B1A7BE /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
02A3C78E1BC4317A00B1A7BE /* GCDWebServer */,
|
||||
02A3C7901BC4317A00B1A7BE /* GCDWebServer.app */,
|
||||
02A3C7921BC4317A00B1A7BE /* GCDWebServers.framework */,
|
||||
02A3C7941BC4317A00B1A7BE /* GCDWebServers.framework */,
|
||||
02A3C7961BC4317A00B1A7BE /* Tests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
02B58CA71AE99CEB009B348C = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
02A3C7841BC4317A00B1A7BE /* GCDWebServer.xcodeproj */,
|
||||
02B58CCF1AE99D8C009B348C /* Frameworks */,
|
||||
0270BC3D1B7CFBFD00010E03 /* RealmJS */,
|
||||
02B58CC01AE99CEC009B348C /* RealmJSTests */,
|
||||
|
@ -257,6 +315,7 @@
|
|||
02B58CCF1AE99D8C009B348C /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
02A3C7A41BC4341500B1A7BE /* libc++.tbd */,
|
||||
02B58CCD1AE99D4D009B348C /* JavaScriptCore.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
|
@ -270,23 +329,24 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0270BC4C1B7CFC0D00010E03 /* RealmJS.h in Headers */,
|
||||
02258FB31BC6E2D00075F13A /* RealmRPC.h in Headers */,
|
||||
0270BC4F1B7CFC0D00010E03 /* RJSArray.hpp in Headers */,
|
||||
0270BC541B7CFC0D00010E03 /* RJSResults.hpp in Headers */,
|
||||
0270BC581B7CFC0D00010E03 /* RJSUtil.hpp in Headers */,
|
||||
0270BC561B7CFC0D00010E03 /* RJSSchema.hpp in Headers */,
|
||||
0270BC521B7CFC0D00010E03 /* RJSRealm.hpp in Headers */,
|
||||
0270BC501B7CFC0D00010E03 /* RJSObject.hpp in Headers */,
|
||||
02601F0E1BA0F3A7007C91FF /* schema.hpp in Headers */,
|
||||
0270BC6C1B7CFC1C00010E03 /* object_store.hpp in Headers */,
|
||||
02601F0A1BA0F0CD007C91FF /* realm_delegate.hpp in Headers */,
|
||||
0270BC541B7CFC0D00010E03 /* RJSResults.hpp in Headers */,
|
||||
02601F121BA10228007C91FF /* transact_log_handler.hpp in Headers */,
|
||||
0270BC681B7CFC1C00010E03 /* object_accessor.hpp in Headers */,
|
||||
0270BC711B7CFC1C00010E03 /* shared_realm.hpp in Headers */,
|
||||
0270BC581B7CFC0D00010E03 /* RJSUtil.hpp in Headers */,
|
||||
0270BC6A1B7CFC1C00010E03 /* object_schema.hpp in Headers */,
|
||||
02601F041BA0F0C4007C91FF /* external_commit_helper.hpp in Headers */,
|
||||
02601F091BA0F0CD007C91FF /* index_set.hpp in Headers */,
|
||||
0270BC6D1B7CFC1C00010E03 /* property.hpp in Headers */,
|
||||
0270BC6F1B7CFC1C00010E03 /* results.hpp in Headers */,
|
||||
0270BC561B7CFC0D00010E03 /* RJSSchema.hpp in Headers */,
|
||||
0270BC521B7CFC0D00010E03 /* RJSRealm.hpp in Headers */,
|
||||
0270BC501B7CFC0D00010E03 /* RJSObject.hpp in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -378,6 +438,12 @@
|
|||
mainGroup = 02B58CA71AE99CEB009B348C;
|
||||
productRefGroup = 02B58CB21AE99CEC009B348C /* Products */;
|
||||
projectDirPath = "";
|
||||
projectReferences = (
|
||||
{
|
||||
ProductGroup = 02A3C7851BC4317A00B1A7BE /* Products */;
|
||||
ProjectRef = 02A3C7841BC4317A00B1A7BE /* GCDWebServer.xcodeproj */;
|
||||
},
|
||||
);
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
02B58CB01AE99CEC009B348C /* RealmJS */,
|
||||
|
@ -387,6 +453,44 @@
|
|||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXReferenceProxy section */
|
||||
02A3C78E1BC4317A00B1A7BE /* GCDWebServer */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = "compiled.mach-o.executable";
|
||||
path = GCDWebServer;
|
||||
remoteRef = 02A3C78D1BC4317A00B1A7BE /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
02A3C7901BC4317A00B1A7BE /* GCDWebServer.app */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.application;
|
||||
path = GCDWebServer.app;
|
||||
remoteRef = 02A3C78F1BC4317A00B1A7BE /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
02A3C7921BC4317A00B1A7BE /* GCDWebServers.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework;
|
||||
path = GCDWebServers.framework;
|
||||
remoteRef = 02A3C7911BC4317A00B1A7BE /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
02A3C7941BC4317A00B1A7BE /* GCDWebServers.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework;
|
||||
path = GCDWebServers.framework;
|
||||
remoteRef = 02A3C7931BC4317A00B1A7BE /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
02A3C7961BC4317A00B1A7BE /* Tests.xctest */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.cfbundle;
|
||||
path = Tests.xctest;
|
||||
remoteRef = 02A3C7951BC4317A00B1A7BE /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
/* End PBXReferenceProxy section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
02B58CAF1AE99CEC009B348C /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
|
@ -447,6 +551,7 @@
|
|||
0270BC511B7CFC0D00010E03 /* RJSObject.mm in Sources */,
|
||||
0270BC4D1B7CFC0D00010E03 /* RealmJS.mm in Sources */,
|
||||
02601F081BA0F0CD007C91FF /* index_set.cpp in Sources */,
|
||||
02258FB41BC6E2D00075F13A /* RealmRPC.mm in Sources */,
|
||||
02601F111BA10228007C91FF /* transact_log_handler.cpp in Sources */,
|
||||
0270BC591B7CFC0D00010E03 /* RJSUtil.mm in Sources */,
|
||||
0270BC551B7CFC0D00010E03 /* RJSResults.mm in Sources */,
|
||||
|
@ -486,6 +591,11 @@
|
|||
02B29A281B7CF7C9008A7E6B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)",
|
||||
);
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
|
@ -495,7 +605,12 @@
|
|||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/examples/ReactExample/node_modules/react-native/React/",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-isystem",
|
||||
core/include,
|
||||
);
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -505,12 +620,22 @@
|
|||
02B29A291B7CF7C9008A7E6B /* GCov_Build */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/examples/ReactExample/node_modules/react-native/React/",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-isystem",
|
||||
core/include,
|
||||
);
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -520,12 +645,22 @@
|
|||
02B29A2A1B7CF7C9008A7E6B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)",
|
||||
);
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/examples/ReactExample/node_modules/react-native/React/",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
"$(OTHER_CFLAGS)",
|
||||
"-isystem",
|
||||
core/include,
|
||||
);
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -636,7 +771,7 @@
|
|||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
|
||||
GCC_NO_COMMON_BLOCKS = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
REALM_HAVE_CONFIG,
|
||||
|
@ -650,7 +785,7 @@
|
|||
);
|
||||
INFOPLIST_FILE = src/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = core;
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
|
@ -674,7 +809,7 @@
|
|||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
|
||||
GCC_NO_COMMON_BLOCKS = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
|
@ -682,7 +817,7 @@
|
|||
);
|
||||
INFOPLIST_FILE = src/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = core;
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
|
@ -710,6 +845,7 @@
|
|||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = tests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
|
@ -724,6 +860,7 @@
|
|||
build/iOS,
|
||||
);
|
||||
INFOPLIST_FILE = tests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
|
@ -788,7 +925,7 @@
|
|||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
|
||||
GCC_NO_COMMON_BLOCKS = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
REALM_HAVE_CONFIG,
|
||||
|
@ -802,7 +939,7 @@
|
|||
);
|
||||
INFOPLIST_FILE = src/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = core;
|
||||
OTHER_CPLUSPLUSFLAGS = (
|
||||
|
@ -830,6 +967,7 @@
|
|||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = tests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
|
||||
0270BCD21B7D095C00010E03 /* libRealmReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0270BCB31B7D04D700010E03 /* libRealmReact.a */; };
|
||||
027798491BBB2F1000C96559 /* ReactExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 027798481BBB2F1000C96559 /* ReactExampleTests.m */; };
|
||||
02A3C7A71BC4347100B1A7BE /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 02A3C7A61BC4347100B1A7BE /* libc++.tbd */; };
|
||||
02BB0BE51B9A06DC004D6DD2 /* RealmJS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0270BCAF1B7D04D700010E03 /* RealmJS.framework */; };
|
||||
02BB0BE61B9A06DC004D6DD2 /* RealmJS.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0270BCAF1B7D04D700010E03 /* RealmJS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
|
||||
|
@ -161,6 +162,7 @@
|
|||
027798461BBB2F1000C96559 /* ReactExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
027798481BBB2F1000C96559 /* ReactExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactExampleTests.m; sourceTree = "<group>"; };
|
||||
0277984A1BBB2F1000C96559 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
02A3C7A61BC4347100B1A7BE /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
|
||||
139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = "<group>"; };
|
||||
139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* ReactExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReactExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -187,6 +189,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
02A3C7A71BC4347100B1A7BE /* libc++.tbd in Frameworks */,
|
||||
0270BCD21B7D095C00010E03 /* libRealmReact.a in Frameworks */,
|
||||
146834051AC3E58100842450 /* libReact.a in Frameworks */,
|
||||
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
|
||||
|
@ -339,6 +342,7 @@
|
|||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
02A3C7A61BC4347100B1A7BE /* libc++.tbd */,
|
||||
13B07FAE1A68108700A75B9A /* ReactExample */,
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||
027798471BBB2F1000C96559 /* ReactExampleTests */,
|
||||
|
@ -382,6 +386,7 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactExample" */;
|
||||
buildPhases = (
|
||||
02A3C7C11BC4597900B1A7BE /* ShellScript */,
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
|
@ -591,6 +596,22 @@
|
|||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
02A3C7C11BC4597900B1A7BE /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "rm -rf ./node_modules/realm\nnpm install realm";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
027798421BBB2F1000C96559 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
|
@ -645,7 +666,7 @@
|
|||
ENABLE_TESTABILITY = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INFOPLIST_FILE = ReactExampleTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.realm.ReactExampleTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
@ -661,7 +682,7 @@
|
|||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INFOPLIST_FILE = ReactExampleTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = io.realm.ReactExampleTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
@ -705,7 +726,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
|
@ -740,7 +761,7 @@
|
|||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/node_modules/react-native/React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -751,7 +772,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
|
@ -780,7 +801,7 @@
|
|||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
"$(SRCROOT)/node_modules/react-native/React/**",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
var Realm = require('realm');
|
||||
var React = require('react-native');
|
||||
|
||||
var {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"start": "node_modules/react-native/packager/packager.sh"
|
||||
},
|
||||
"dependencies": {
|
||||
"react-native": "0.11.4"
|
||||
"react-native": "0.11.4",
|
||||
"realm": "file:../../lib"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"root": true,
|
||||
"extends": "eslint:recommended",
|
||||
"env": {
|
||||
"commonjs": true,
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
},
|
||||
"rules": {
|
||||
"comma-dangle": 0,
|
||||
"no-unused-vars": 1,
|
||||
"strict": [2, "global"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
if (typeof Realm != 'undefined') {
|
||||
module.exports = Realm; // eslint-disable-line no-undef
|
||||
} else {
|
||||
module.exports = require('./realm');
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
'use strict';
|
||||
|
||||
let rpc = require('./rpc');
|
||||
let util = require('./util');
|
||||
|
||||
let idKey = util.idKey;
|
||||
let realmKey = util.realmKey;
|
||||
let resizeListKey = util.resizeListKey;
|
||||
let prototype = {};
|
||||
|
||||
exports.create = create;
|
||||
|
||||
[
|
||||
'pop',
|
||||
'shift',
|
||||
'push',
|
||||
'unshift',
|
||||
'splice',
|
||||
].forEach(function(name) {
|
||||
Object.defineProperty(prototype, name, {
|
||||
value: function() {
|
||||
let listId = this[idKey];
|
||||
let realmId = this[realmKey];
|
||||
|
||||
if (!listId || !realmId) {
|
||||
throw new TypeError(name + ' method was not called on a List!');
|
||||
}
|
||||
|
||||
let result = rpc.callListMethod(realmId, listId, name, Array.from(arguments));
|
||||
this[resizeListKey]();
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function create(realmId, info) {
|
||||
let list = util.createList(prototype, getterForLength, getterForIndex, setterForIndex);
|
||||
let size = info.size;
|
||||
|
||||
list[realmKey] = realmId;
|
||||
list[idKey] = info.id;
|
||||
|
||||
list[resizeListKey](size);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
function getterForLength() {
|
||||
return rpc.getListSize(this[realmKey], this[idKey]);
|
||||
}
|
||||
|
||||
function getterForIndex(index) {
|
||||
return function() {
|
||||
return rpc.getListItem(this[realmKey], this[idKey], index);
|
||||
};
|
||||
}
|
||||
|
||||
function setterForIndex(index) {
|
||||
return function(value) {
|
||||
rpc.setListItem(this[realmKey], this[idKey], index, value);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
'use strict';
|
||||
|
||||
let rpc = require('./rpc');
|
||||
let util = require('./util');
|
||||
|
||||
let idKey = util.idKey;
|
||||
let realmKey = util.realmKey;
|
||||
let registeredConstructors = {};
|
||||
|
||||
exports.create = create;
|
||||
exports.registerConstructors = registerConstructors;
|
||||
|
||||
function create(realmId, info) {
|
||||
let schema = info.schema;
|
||||
let constructor = (registeredConstructors[realmId] || {})[schema.name];
|
||||
let object = constructor ? Object.create(constructor.prototype) : {};
|
||||
let props = {};
|
||||
|
||||
object[realmKey] = realmId;
|
||||
object[idKey] = info.id;
|
||||
|
||||
for (let prop of schema.properties) {
|
||||
let name = prop.name;
|
||||
|
||||
props[name] = {
|
||||
get: getterForProperty(name),
|
||||
set: setterForProperty(name),
|
||||
};
|
||||
}
|
||||
|
||||
Object.defineProperties(object, props);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
function registerConstructors(realmId, constructors) {
|
||||
registeredConstructors[realmId] = constructors;
|
||||
}
|
||||
|
||||
function getterForProperty(name) {
|
||||
return function() {
|
||||
return rpc.getObjectProperty(this[realmKey], this[idKey], name);
|
||||
};
|
||||
}
|
||||
|
||||
function setterForProperty(name) {
|
||||
return function(value) {
|
||||
rpc.setObjectProperty(this[realmKey], this[idKey], name, value);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "realm",
|
||||
"version": "0.0.1",
|
||||
"private": true
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
'use strict';
|
||||
|
||||
let lists = require('./lists');
|
||||
let objects = require('./objects');
|
||||
let results = require('./results');
|
||||
let rpc = require('./rpc');
|
||||
let types = require('./types');
|
||||
let util = require('./util');
|
||||
|
||||
let realmKey = util.realmKey;
|
||||
|
||||
// TODO: DATA
|
||||
rpc.registerTypeConverter(types.DATE, (_, info) => new Date(info.value));
|
||||
rpc.registerTypeConverter(types.LIST, lists.create);
|
||||
rpc.registerTypeConverter(types.OBJECT, objects.create);
|
||||
rpc.registerTypeConverter('ObjectTypesRESULTS', results.create);
|
||||
|
||||
class Realm {
|
||||
constructor(config) {
|
||||
let schema = typeof config == 'object' && config.schema;
|
||||
let constructors = {};
|
||||
|
||||
for (let i = 0, len = schema ? schema.length : 0; i < len; i++) {
|
||||
let item = schema[i];
|
||||
let proto = item.prototype;
|
||||
|
||||
if (proto && proto.schema) {
|
||||
schema.splice(i, 1, proto.schema);
|
||||
constructors[proto.schema.name] = item;
|
||||
}
|
||||
}
|
||||
|
||||
let realmId = this[realmKey] = rpc.createRealm(config);
|
||||
|
||||
objects.registerConstructors(realmId, constructors);
|
||||
}
|
||||
|
||||
addNotification(callback) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
write(callback) {
|
||||
let realmId = this[realmKey];
|
||||
|
||||
if (!realmId) {
|
||||
throw new TypeError('write method was not called on a Realm object!');
|
||||
}
|
||||
if (typeof callback != 'function') {
|
||||
throw new TypeError('Realm.write() must be passed a function!');
|
||||
}
|
||||
|
||||
rpc.beginTransaction(realmId);
|
||||
|
||||
try {
|
||||
callback();
|
||||
} catch (e) {
|
||||
rpc.cancelTransaction(realmId);
|
||||
throw e;
|
||||
}
|
||||
|
||||
rpc.commitTransaction(realmId);
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
'create',
|
||||
'delete',
|
||||
'deleteAll',
|
||||
'objects',
|
||||
].forEach(function(name) {
|
||||
Object.defineProperty(Realm.prototype, name, {
|
||||
value: function() {
|
||||
let realmId = this[realmKey];
|
||||
|
||||
if (!realmId) {
|
||||
throw new TypeError(name + ' method was not called on a Realm object!');
|
||||
}
|
||||
|
||||
return rpc.callRealmMethod(realmId, name, Array.from(arguments));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Object.defineProperty(Realm, 'Types', {value: types});
|
||||
|
||||
module.exports = Realm;
|
|
@ -0,0 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
let rpc = require('./rpc');
|
||||
let util = require('./util');
|
||||
|
||||
let idKey = util.idKey;
|
||||
let realmKey = util.realmKey;
|
||||
let resizeListKey = util.resizeListKey;
|
||||
|
||||
exports.create = create;
|
||||
|
||||
function create(realmId, info) {
|
||||
let results = util.createList(null, getterForLength, getterForIndex);
|
||||
let size = info.size;
|
||||
|
||||
results[realmKey] = realmId;
|
||||
results[idKey] = info.id;
|
||||
|
||||
results[resizeListKey](size);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
function getterForLength() {
|
||||
return rpc.getResultsSize(this[realmKey], this[idKey]);
|
||||
}
|
||||
|
||||
function getterForIndex(index) {
|
||||
return function() {
|
||||
return rpc.getResultsItem(this[realmKey], this[idKey], index);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
'use strict';
|
||||
|
||||
let util = require('./util');
|
||||
|
||||
let DEVICE_HOST = 'localhost:8082';
|
||||
|
||||
let idKey = util.idKey;
|
||||
let realmKey = util.realmKey;
|
||||
let typeConverters = {};
|
||||
let XMLHttpRequest = window.XMLHttpRequest;
|
||||
|
||||
// Check if XMLHttpRequest has been overridden, and get the native one if that's the case.
|
||||
if (XMLHttpRequest.__proto__ != window.XMLHttpRequestEventTarget) {
|
||||
let override = XMLHttpRequest;
|
||||
delete window.XMLHttpRequest;
|
||||
XMLHttpRequest = window.XMLHttpRequest;
|
||||
window.XMLHttpRequest = override;
|
||||
}
|
||||
|
||||
exports.registerTypeConverter = registerTypeConverter;
|
||||
|
||||
exports.createRealm = createRealm;
|
||||
exports.callRealmMethod = callRealmMethod;
|
||||
|
||||
exports.getObjectProperty = getObjectProperty;
|
||||
exports.setObjectProperty = setObjectProperty;
|
||||
|
||||
exports.getListItem = getListItem;
|
||||
exports.setListItem = setListItem;
|
||||
exports.getListSize = getListSize;
|
||||
exports.callListMethod = callListMethod;
|
||||
|
||||
exports.getResultsItem = getResultsItem;
|
||||
exports.getResultsSize = getResultsSize;
|
||||
|
||||
exports.beginTransaction = beginTransaction;
|
||||
exports.cancelTransaction = cancelTransaction;
|
||||
exports.commitTransaction = commitTransaction;
|
||||
|
||||
function registerTypeConverter(type, handler) {
|
||||
typeConverters[type] = handler;
|
||||
}
|
||||
|
||||
function createRealm(config) {
|
||||
return sendRequest('create_realm', config);
|
||||
}
|
||||
|
||||
function callRealmMethod(realmId, name, args) {
|
||||
if (args) {
|
||||
args = args.map((arg) => serialize(realmId, arg));
|
||||
}
|
||||
|
||||
let result = sendRequest('call_realm_method', {realmId, name, arguments: args});
|
||||
return deserialize(realmId, result);
|
||||
}
|
||||
|
||||
function getObjectProperty(realmId, objectId, name) {
|
||||
let result = sendRequest('get_property', {realmId, objectId, name});
|
||||
return deserialize(realmId, result);
|
||||
}
|
||||
|
||||
function setObjectProperty(realmId, objectId, name, value) {
|
||||
value = serialize(realmId, value);
|
||||
sendRequest('set_property', {realmId, objectId, name, value});
|
||||
}
|
||||
|
||||
function getListItem(realmId, listId, index) {
|
||||
let result = sendRequest('get_list_item', {realmId, listId, index});
|
||||
return deserialize(realmId, result);
|
||||
}
|
||||
|
||||
function setListItem(realmId, listId, index, value) {
|
||||
sendRequest('set_list_item', {realmId, listId, index, value});
|
||||
}
|
||||
|
||||
function getListSize(realmId, listId) {
|
||||
return sendRequest('get_list_size', {realmId, listId});
|
||||
}
|
||||
|
||||
function callListMethod(realmId, listId, name, args) {
|
||||
if (args) {
|
||||
args = args.map((arg) => serialize(realmId, arg));
|
||||
}
|
||||
|
||||
let result = sendRequest('call_list_method', {realmId, listId, name, arguments: args});
|
||||
return deserialize(realmId, result);
|
||||
}
|
||||
|
||||
function getResultsItem(realmId, resultsId, index) {
|
||||
let result = sendRequest('get_results_item', {realmId, resultsId, index});
|
||||
return deserialize(realmId, result);
|
||||
}
|
||||
|
||||
function getResultsSize(realmId, resultsId) {
|
||||
return sendRequest('get_results_size', {realmId, resultsId});
|
||||
}
|
||||
|
||||
function beginTransaction(realmId) {
|
||||
sendRequest('begin_transaction', {realmId});
|
||||
}
|
||||
|
||||
function cancelTransaction(realmId) {
|
||||
sendRequest('cancel_transaction', {realmId});
|
||||
}
|
||||
|
||||
function commitTransaction(realmId) {
|
||||
sendRequest('commit_transaction', {realmId});
|
||||
}
|
||||
|
||||
function serialize(realmId, value) {
|
||||
if (!value || typeof value != 'object') {
|
||||
return {value: value};
|
||||
}
|
||||
|
||||
let id = value[idKey];
|
||||
if (id) {
|
||||
if (value[realmKey] != realmId) {
|
||||
throw new Error('Unable to serialize value from another Realm');
|
||||
}
|
||||
|
||||
return {id: id};
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
let array = value.map((item) => serialize(realmId, item));
|
||||
return {value: array};
|
||||
}
|
||||
|
||||
let object = {};
|
||||
for (let key in value) {
|
||||
object[key] = serialize(realmId, value[key]);
|
||||
}
|
||||
return {value: object};
|
||||
}
|
||||
|
||||
function deserialize(realmId, info) {
|
||||
let type = info.type;
|
||||
let handler = type && typeConverters[type];
|
||||
if (handler) {
|
||||
return handler(realmId, info);
|
||||
}
|
||||
|
||||
let value = info.value;
|
||||
if (value && Array.isArray(value)) {
|
||||
return value.map((item) => deserialize(realmId, item));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function sendRequest(command, data) {
|
||||
let body = JSON.stringify(data);
|
||||
let request = new XMLHttpRequest();
|
||||
let url = 'http://' + DEVICE_HOST + '/' + command;
|
||||
|
||||
request.open('POST', url, false);
|
||||
request.send(body);
|
||||
|
||||
if (request.status != 200) {
|
||||
throw new Error(request.responseText);
|
||||
}
|
||||
|
||||
let response = JSON.parse(request.responseText);
|
||||
|
||||
if (!response || response.error) {
|
||||
throw new Error((response && response.error) || 'Invalid response for "' + command + '"');
|
||||
}
|
||||
|
||||
return response.result;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
'use strict';
|
||||
|
||||
let types = {};
|
||||
|
||||
[
|
||||
'BOOL',
|
||||
'INT',
|
||||
'FLOAT',
|
||||
'DOUBLE',
|
||||
'STRING',
|
||||
'DATE',
|
||||
'DATA',
|
||||
'OBJECT',
|
||||
'LIST',
|
||||
].forEach(function(type) {
|
||||
types[type] = 'PropTypes' + type;
|
||||
});
|
||||
|
||||
module.exports = Object.freeze(types);
|
|
@ -0,0 +1,47 @@
|
|||
'use strict';
|
||||
|
||||
let idKey = exports.idKey = Symbol();
|
||||
let realmKey = exports.realmKey = Symbol();
|
||||
let resizeListKey = exports.resizeListKey = Symbol();
|
||||
|
||||
exports.createList = createList;
|
||||
|
||||
function createList(prototype, getterForLength, getterForIndex, setterForIndex) {
|
||||
var list = prototype ? Object.create(prototype) : {};
|
||||
var size = 0;
|
||||
|
||||
Object.defineProperty(list, 'length', {get: getterForLength});
|
||||
|
||||
list[resizeListKey] = function(length) {
|
||||
if (length == null) {
|
||||
length = this.length;
|
||||
}
|
||||
if (length == size) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (length > size) {
|
||||
let props = {};
|
||||
|
||||
for (let i = size; i < length; i++) {
|
||||
props[i] = {
|
||||
get: getterForIndex(i),
|
||||
set: setterForIndex && setterForIndex(i),
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
};
|
||||
}
|
||||
|
||||
Object.defineProperties(this, props);
|
||||
}
|
||||
else if (length < size) {
|
||||
for (let i = size - 1; i >= length; i--) {
|
||||
delete this[i];
|
||||
}
|
||||
}
|
||||
|
||||
size = length;
|
||||
};
|
||||
|
||||
return list;
|
||||
}
|
|
@ -21,6 +21,7 @@
|
|||
#include "RJSUtil.hpp"
|
||||
#include "object_accessor.hpp"
|
||||
|
||||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||
using namespace realm;
|
||||
|
||||
size_t ObjectArray::size() {
|
||||
|
@ -197,15 +198,16 @@ JSObjectRef RJSArrayCreate(JSContextRef ctx, realm::ObjectArray *array) {
|
|||
return RJSWrapObject<ObjectArray *>(ctx, RJSArrayClass(), array);
|
||||
}
|
||||
|
||||
const JSStaticFunction RJSArrayFuncs[] = {
|
||||
{"push", ArrayPush, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"pop", ArrayPop, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"shift", ArrayShift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"unshift", ArrayUnshift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"splice", ArraySplice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
JSClassRef RJSArrayClass() {
|
||||
const JSStaticFunction arrayFuncs[] = {
|
||||
{"push", ArrayPush, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"pop", ArrayPop, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"shift", ArrayShift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"unshift", ArrayUnshift, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"splice", ArraySplice, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{NULL, NULL},
|
||||
};
|
||||
static JSClassRef s_arrayClass = RJSCreateWrapperClass<Object>("RealmArray", ArrayGetProperty, NULL, arrayFuncs, NULL, ArrayPropertyNames);
|
||||
static JSClassRef s_arrayClass = RJSCreateWrapperClass<Object>("RealmArray", ArrayGetProperty, NULL, RJSArrayFuncs, NULL, ArrayPropertyNames);
|
||||
return s_arrayClass;
|
||||
}
|
||||
|
|
|
@ -34,5 +34,8 @@ namespace realm {
|
|||
};
|
||||
}
|
||||
|
||||
extern const JSStaticFunction RJSArrayFuncs[];
|
||||
JSClassRef RJSArrayClass();
|
||||
JSObjectRef RJSArrayCreate(JSContextRef ctx, realm::ObjectArray *array);
|
||||
|
||||
JSValueRef ArrayGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException);
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import "RJSUtil.hpp"
|
||||
#import "shared_realm.hpp"
|
||||
#import "object_accessor.hpp"
|
||||
|
||||
namespace realm {
|
||||
class Object;
|
||||
}
|
||||
|
||||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||
|
||||
JSClassRef RJSObjectClass();
|
||||
JSObjectRef RJSObjectCreate(JSContextRef ctx, realm::Object object);
|
||||
|
||||
JSValueRef ObjectGetProperty(JSContextRef ctx, JSObjectRef jsObject, JSStringRef jsPropertyName, JSValueRef* exception);
|
||||
bool ObjectSetProperty(JSContextRef ctx, JSObjectRef jsObject, JSStringRef jsPropertyName, JSValueRef value, JSValueRef* exception);
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#import "object_store.hpp"
|
||||
#import "object_accessor.hpp"
|
||||
|
||||
using RJSAccessor = realm::NativeAccessor<JSValueRef, JSContextRef>;
|
||||
using namespace realm;
|
||||
|
||||
JSValueRef ObjectGetProperty(JSContextRef ctx, JSObjectRef jsObject, JSStringRef jsPropertyName, JSValueRef* exception) {
|
||||
|
@ -69,7 +70,6 @@ JSValueRef ObjectGetProperty(JSContextRef ctx, JSObjectRef jsObject, JSStringRef
|
|||
auto arrayObjectSchema = obj->realm->config().schema->find(prop->object_type);
|
||||
return RJSArrayCreate(ctx, new ObjectArray(obj->realm, *arrayObjectSchema, static_cast<LinkViewRef>(obj->row.get_linklist(prop->table_column))));
|
||||
}
|
||||
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#import "RJSUtil.hpp"
|
||||
|
||||
extern const JSStaticFunction RJSRealmFuncs[];
|
||||
|
||||
JSClassRef RJSRealmClass();
|
||||
JSClassRef RJSRealmConstructorClass();
|
||||
JSClassRef RJSNotificationClass();
|
||||
|
@ -25,3 +27,4 @@ JSClassRef RJSNotificationClass();
|
|||
std::string RJSDefaultPath();
|
||||
void RJSSetDefaultPath(std::string path);
|
||||
|
||||
JSObjectRef RealmConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* jsException);
|
||||
|
|
|
@ -409,18 +409,18 @@ void RJSNotificationFinalize(JSObjectRef object) {
|
|||
RJSFinalize<Notification *>(object);
|
||||
}
|
||||
|
||||
const JSStaticFunction RJSRealmFuncs[] = {
|
||||
{"objects", RealmObjects, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"create", RealmCreateObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"delete", RealmDelete, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"deleteAll", RealmDeleteAll, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"write", RealmWrite, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"addNotification", RealmAddNotification, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
JSClassRef RJSRealmClass() {
|
||||
const JSStaticFunction realmFuncs[] = {
|
||||
{"objects", RealmObjects, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"create", RealmCreateObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"delete", RealmDelete, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"deleteAll", RealmDeleteAll, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"write", RealmWrite, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{"addNotification", RealmAddNotification, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
|
||||
{NULL, NULL},
|
||||
};
|
||||
static JSClassRef s_realmClass = RJSCreateWrapperClass<SharedRealm *>("Realm", RealmGetProperty, NULL, realmFuncs);
|
||||
static JSClassRef s_realmClass = RJSCreateWrapperClass<SharedRealm *>("Realm", RealmGetProperty, NULL, RJSRealmFuncs);
|
||||
return s_realmClass;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,3 +26,6 @@ namespace realm {
|
|||
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);
|
||||
|
||||
JSValueRef ResultsGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* jsException);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <JavaScriptCore/JavaScriptCore.h>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include "property.hpp"
|
||||
#include "schema.hpp"
|
||||
|
||||
template<typename T>
|
||||
|
@ -55,7 +56,11 @@ JSClassRef RJSCreateWrapperClass(const char * name, JSObjectGetPropertyCallback
|
|||
|
||||
JSObjectRef RJSRegisterGlobalClass(JSContextRef ctx, JSObjectRef globalObject, JSClassRef classRef, const char * name, JSValueRef *exception);
|
||||
|
||||
std::string RJSTypeGet(realm::PropertyType propertyType);
|
||||
std::string RJSTypeGet(std::string typeString);
|
||||
|
||||
std::string RJSStringForJSString(JSStringRef jsString);
|
||||
std::string RJSStringForValue(JSContextRef ctx, JSValueRef value);
|
||||
std::string RJSValidatedStringForValue(JSContextRef ctx, JSValueRef value, const char * name = nullptr);
|
||||
|
||||
JSStringRef RJSStringForString(const std::string &str);
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#import "RJSUtil.hpp"
|
||||
|
||||
using namespace realm;
|
||||
|
||||
JSObjectRef RJSRegisterGlobalClass(JSContextRef ctx, JSObjectRef globalObject, JSClassRef classRef, const char * name, JSValueRef *exception) {
|
||||
JSObjectRef classObject = JSObjectMake(ctx, classRef, NULL);
|
||||
JSStringRef nameString = JSStringCreateWithUTF8CString(name);
|
||||
|
@ -43,6 +45,25 @@ JSValueRef RJSMakeError(JSContextRef ctx, const std::string &message) {
|
|||
return JSObjectMakeError(ctx, 1, &value, NULL);
|
||||
}
|
||||
|
||||
std::string RJSTypeGet(PropertyType propertyType) {
|
||||
switch (propertyType) {
|
||||
case PropertyTypeBool: return RJSTypeGet("BOOL");
|
||||
case PropertyTypeInt: return RJSTypeGet("INT");
|
||||
case PropertyTypeFloat: return RJSTypeGet("FLOAT");
|
||||
case PropertyTypeDouble:return RJSTypeGet("DOUBLE");
|
||||
case PropertyTypeString:return RJSTypeGet("STRING");
|
||||
case PropertyTypeDate: return RJSTypeGet("DATE");
|
||||
case PropertyTypeData: return RJSTypeGet("DATA");
|
||||
case PropertyTypeObject:return RJSTypeGet("OBJECT");
|
||||
case PropertyTypeArray: return RJSTypeGet("LIST");
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::string RJSTypeGet(std::string propertyTypeString) {
|
||||
return "PropTypes" + propertyTypeString;
|
||||
}
|
||||
|
||||
std::string RJSStringForJSString(JSStringRef jsString) {
|
||||
std::string str;
|
||||
size_t maxSize = JSStringGetMaximumUTF8CStringSize(jsString);
|
||||
|
@ -51,6 +72,19 @@ std::string RJSStringForJSString(JSStringRef jsString) {
|
|||
return str;
|
||||
}
|
||||
|
||||
std::string RJSStringForValue(JSContextRef ctx, JSValueRef value) {
|
||||
JSValueRef *exception;
|
||||
JSStringRef jsString = JSValueToStringCopy(ctx, value, exception);
|
||||
if (!jsString) {
|
||||
throw RJSException(ctx, *exception);
|
||||
}
|
||||
|
||||
std::string string = RJSStringForJSString(jsString);
|
||||
JSStringRelease(jsString);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
std::string RJSValidatedStringForValue(JSContextRef ctx, JSValueRef value, const char * name) {
|
||||
if (!JSValueIsString(ctx, value)) {
|
||||
if (name) {
|
||||
|
@ -61,13 +95,7 @@ std::string RJSValidatedStringForValue(JSContextRef ctx, JSValueRef value, const
|
|||
}
|
||||
}
|
||||
|
||||
JSValueRef *exception;
|
||||
JSStringRef jsString = JSValueToStringCopy(ctx, value, exception);
|
||||
if (!jsString) {
|
||||
throw RJSException(ctx, *exception);
|
||||
}
|
||||
|
||||
return RJSStringForJSString(jsString);
|
||||
return RJSStringForValue(ctx, value);
|
||||
}
|
||||
|
||||
JSStringRef RJSStringForString(const std::string &str) {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <JavaScriptCore/JavaScriptCore.h>
|
||||
#import <RealmJS/RealmRPC.h>
|
||||
|
||||
@interface RealmJS : NSObject
|
||||
|
||||
|
|
|
@ -19,9 +19,10 @@
|
|||
#import "RealmJS.h"
|
||||
#import "RJSRealm.hpp"
|
||||
#import "RJSObject.hpp"
|
||||
#import "RJSUtil.hpp"
|
||||
|
||||
JSValueRef RJSTypeGet(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) {
|
||||
return RJSValueForString(ctx, "PropTypes" + RJSStringForJSString(propertyName));
|
||||
return RJSValueForString(ctx, RJSTypeGet(RJSStringForJSString(propertyName)));
|
||||
}
|
||||
|
||||
JSClassRef RJSRealmTypeClass() {
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2015 Realm Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface RJSRPCServer : NSObject
|
||||
|
||||
- (NSDictionary *)performRequest:(NSString *)name args:(NSDictionary *)args;
|
||||
|
||||
@end
|
|
@ -0,0 +1,352 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2015 Realm Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import "RealmRPC.h"
|
||||
#import <JavaScriptCore/JavaScriptCore.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "RealmJS.h"
|
||||
#include "RJSObject.hpp"
|
||||
#include "RJSResults.hpp"
|
||||
#include "RJSArray.hpp"
|
||||
#include "RJSRealm.hpp"
|
||||
#include "RJSUtil.hpp"
|
||||
|
||||
#include "object_accessor.hpp"
|
||||
#include "shared_realm.hpp"
|
||||
#include "results.hpp"
|
||||
|
||||
using RPCObjectID = u_int64_t;
|
||||
using RPCRequest = std::function<NSDictionary *(NSDictionary *dictionary)>;
|
||||
|
||||
@implementation RJSRPCServer {
|
||||
JSGlobalContextRef _context;
|
||||
std::map<std::string, RPCRequest> _requests;
|
||||
std::map<RPCObjectID, JSObjectRef> _objects;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_context = JSGlobalContextCreate(NULL);
|
||||
_requests["/create_realm"] = [=](NSDictionary *dict) {
|
||||
// We should have a method for serializing schema rather than relying on JSValue
|
||||
JSValueRef value = [[JSValue valueWithObject:dict
|
||||
inContext:[JSContext contextWithJSGlobalContextRef:_context]] JSValueRef];
|
||||
JSValueRef ex = NULL;
|
||||
RPCObjectID realmId = [self storeObject:RealmConstructor(_context, NULL, 1, &value, &ex)];
|
||||
if (ex) {
|
||||
return @{@"error": @(RJSStringForValue(_context, ex).c_str())};
|
||||
}
|
||||
return @{@"result": @(realmId)};
|
||||
};
|
||||
_requests["/begin_transaction"] = [=](NSDictionary *dict) {
|
||||
RPCObjectID realmId = [dict[@"realmId"] unsignedLongValue];
|
||||
RJSGetInternal<realm::SharedRealm *>(_objects[realmId])->get()->begin_transaction();
|
||||
return @{};
|
||||
};
|
||||
_requests["/cancel_transaction"] = [=](NSDictionary *dict) {
|
||||
RPCObjectID realmId = [dict[@"realmId"] unsignedLongValue];
|
||||
RJSGetInternal<realm::SharedRealm *>(_objects[realmId])->get()->cancel_transaction();
|
||||
return @{};
|
||||
};
|
||||
_requests["/commit_transaction"] = [=](NSDictionary *dict) {
|
||||
RPCObjectID realmId = [dict[@"realmId"] unsignedLongValue];
|
||||
RJSGetInternal<realm::SharedRealm *>(_objects[realmId])->get()->commit_transaction();
|
||||
return @{};
|
||||
};
|
||||
_requests["/call_realm_method"] = [=](NSDictionary *dict) {
|
||||
NSString *name = dict[@"name"];
|
||||
return [self performObjectMethod:name.UTF8String
|
||||
classMethods:RJSRealmFuncs
|
||||
args:dict[@"arguments"]
|
||||
objectId:[dict[@"realmId"] unsignedLongValue]];
|
||||
};
|
||||
_requests["/get_property"] = [=](NSDictionary *dict) {
|
||||
JSValueRef exception = NULL;
|
||||
NSString *name = dict[@"name"];
|
||||
JSStringRef propString = RJSStringForString(name.UTF8String);
|
||||
RPCObjectID objectId = [dict[@"objectId"] unsignedLongValue];
|
||||
JSValueRef propertyValue = ObjectGetProperty(_context, _objects[objectId], propString, &exception);
|
||||
JSStringRelease(propString);
|
||||
|
||||
if (exception) {
|
||||
return @{@"error": @(RJSStringForValue(_context, exception).c_str())};
|
||||
}
|
||||
return @{@"result": [self resultForJSValue:propertyValue]};
|
||||
};
|
||||
_requests["/set_property"] = [=](NSDictionary *dict) {
|
||||
JSStringRef propString = RJSStringForString([dict[@"name"] UTF8String]);
|
||||
RPCObjectID realmId = [dict[@"objectId"] unsignedLongValue];
|
||||
JSValueRef value = [self valueFromDictionary:dict[@"value"]];
|
||||
JSValueRef exception = NULL;
|
||||
|
||||
ObjectSetProperty(_context, _objects[realmId], propString, value, &exception);
|
||||
JSStringRelease(propString);
|
||||
|
||||
return exception ? @{@"error": @(RJSStringForValue(_context, exception).c_str())} : @{};
|
||||
};
|
||||
_requests["/dispose_object"] = [=](NSDictionary *dict) {
|
||||
RPCObjectID oid = [dict[@"id"] unsignedLongValue];
|
||||
JSValueUnprotect(_context, _objects[oid]);
|
||||
_objects.erase(oid);
|
||||
return @{};
|
||||
};
|
||||
_requests["/get_results_size"] = [=](NSDictionary *dict) {
|
||||
RPCObjectID resultsId = [dict[@"resultsId"] unsignedLongValue];
|
||||
|
||||
JSValueRef exception = NULL;
|
||||
static JSStringRef lengthPropertyName = JSStringCreateWithUTF8CString("length");
|
||||
JSValueRef lengthValue = ResultsGetProperty(_context, _objects[resultsId], lengthPropertyName, &exception);
|
||||
size_t length = JSValueToNumber(_context, lengthValue, &exception);
|
||||
|
||||
if (exception) {
|
||||
return @{@"error": @(RJSStringForValue(_context, exception).c_str())};
|
||||
}
|
||||
return @{@"result": @(length)};
|
||||
};
|
||||
_requests["/get_results_item"] = [=](NSDictionary *dict) {
|
||||
RPCObjectID resultsId = [dict[@"resultsId"] unsignedLongValue];
|
||||
long index = [dict[@"index"] longValue];
|
||||
|
||||
JSValueRef exception = NULL;
|
||||
JSStringRef indexPropertyName = JSStringCreateWithUTF8CString(std::to_string(index).c_str());
|
||||
JSValueRef objectValue = ResultsGetProperty(_context, _objects[resultsId], indexPropertyName, &exception);
|
||||
JSStringRelease(indexPropertyName);
|
||||
|
||||
if (exception) {
|
||||
return @{@"error": @(RJSStringForValue(_context, exception).c_str())};
|
||||
}
|
||||
return @{@"result": [self resultForJSValue:objectValue]};
|
||||
};
|
||||
_requests["/get_list_size"] = [=](NSDictionary *dict) {
|
||||
RPCObjectID listId = [dict[@"listId"] unsignedLongValue];
|
||||
|
||||
JSValueRef exception = NULL;
|
||||
static JSStringRef lengthPropertyName = JSStringCreateWithUTF8CString("length");
|
||||
JSValueRef lengthValue = ArrayGetProperty(_context, _objects[listId], lengthPropertyName, &exception);
|
||||
size_t length = JSValueToNumber(_context, lengthValue, &exception);
|
||||
|
||||
if (exception) {
|
||||
return @{@"error": @(RJSStringForValue(_context, exception).c_str())};
|
||||
}
|
||||
return @{@"result": @(length)};
|
||||
};
|
||||
_requests["/get_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 objectValue = ArrayGetProperty(_context, _objects[listId], indexPropertyName, &exception);
|
||||
JSStringRelease(indexPropertyName);
|
||||
|
||||
if (exception) {
|
||||
return @{@"error": @(RJSStringForValue(_context, exception).c_str())};
|
||||
}
|
||||
|
||||
return @{@"result": [self resultForJSValue:objectValue]};
|
||||
};
|
||||
_requests["/call_list_method"] = [=](NSDictionary *dict) {
|
||||
NSString *name = dict[@"name"];
|
||||
return [self performObjectMethod:name.UTF8String
|
||||
classMethods:RJSArrayFuncs
|
||||
args:dict[@"arguments"]
|
||||
objectId:[dict[@"listId"] unsignedLongValue]];
|
||||
};
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary *)performRequest:(NSString *)name args:(NSDictionary *)args {
|
||||
// perform all realm ops on the main thread
|
||||
RPCRequest action = _requests[name.UTF8String];
|
||||
__block id response;
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
try {
|
||||
response = action(args);
|
||||
} catch (std::exception &exception) {
|
||||
response = @{@"error": [@"exception thrown: " stringByAppendingString:@(exception.what())]};
|
||||
}
|
||||
});
|
||||
return response;
|
||||
}
|
||||
|
||||
- (NSDictionary *)performObjectMethod:(const char *)name
|
||||
classMethods:(const JSStaticFunction [])methods
|
||||
args:(NSArray *)args
|
||||
objectId:(RPCObjectID)oid {
|
||||
NSUInteger count = args.count;
|
||||
JSValueRef argValues[count];
|
||||
for (NSUInteger i = 0; i < count; i++) {
|
||||
argValues[i] = [self valueFromDictionary:args[i]];
|
||||
}
|
||||
|
||||
size_t index = 0;
|
||||
while (methods[index].name) {
|
||||
if (!strcmp(methods[index].name, name)) {
|
||||
JSValueRef ex = NULL;
|
||||
JSValueRef ret = methods[index].callAsFunction(_context, NULL, _objects[oid], count, argValues, &ex);
|
||||
if (ex) {
|
||||
return @{@"error": @(RJSStringForValue(_context, ex).c_str())};
|
||||
}
|
||||
return @{@"result": [self resultForJSValue:ret]};
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return @{@"error": @"invalid method"};
|
||||
}
|
||||
|
||||
- (RPCObjectID)storeObject:(JSObjectRef)object {
|
||||
static RPCObjectID s_next_id = 1;
|
||||
RPCObjectID next_id = s_next_id++;
|
||||
JSValueProtect(_context, object);
|
||||
_objects[next_id] = object;
|
||||
return next_id;
|
||||
}
|
||||
|
||||
- (NSDictionary *)resultForJSValue:(JSValueRef)value {
|
||||
switch (JSValueGetType(_context, value)) {
|
||||
case kJSTypeUndefined:
|
||||
return @{};
|
||||
case kJSTypeNull:
|
||||
return @{@"value": [NSNull null]};
|
||||
case kJSTypeBoolean:
|
||||
return @{@"value": @(JSValueToBoolean(_context, value))};
|
||||
case kJSTypeNumber:
|
||||
return @{@"value": @(JSValueToNumber(_context, value, NULL))};
|
||||
case kJSTypeString:
|
||||
return @{@"value": @(RJSStringForValue(_context, value).c_str())};
|
||||
case kJSTypeObject:
|
||||
break;
|
||||
}
|
||||
|
||||
JSObjectRef jsObject = JSValueToObject(_context, value, NULL);
|
||||
|
||||
if (JSValueIsObjectOfClass(_context, value, RJSObjectClass())) {
|
||||
realm::Object *object = RJSGetInternal<realm::Object *>(jsObject);
|
||||
RPCObjectID oid = [self storeObject:jsObject];
|
||||
return @{
|
||||
@"type": @(RJSTypeGet(realm::PropertyTypeObject).c_str()),
|
||||
@"id": @(oid),
|
||||
@"schema": [self objectSchemaToJSONObject:object->object_schema]
|
||||
};
|
||||
}
|
||||
else if (JSValueIsObjectOfClass(_context, value, RJSArrayClass())) {
|
||||
realm::ObjectArray *array = RJSGetInternal<realm::ObjectArray *>(jsObject);
|
||||
RPCObjectID oid = [self storeObject:jsObject];
|
||||
return @{
|
||||
@"type": @(RJSTypeGet(realm::PropertyTypeArray).c_str()),
|
||||
@"id": @(oid),
|
||||
@"size": @(array->link_view->size()),
|
||||
@"schema": [self objectSchemaToJSONObject:array->object_schema]
|
||||
};
|
||||
}
|
||||
else if (JSValueIsObjectOfClass(_context, value, RJSResultsClass())) {
|
||||
realm::Results *results = RJSGetInternal<realm::Results *>(jsObject);
|
||||
RPCObjectID oid = [self storeObject:jsObject];
|
||||
return @{
|
||||
@"type": @"ObjectTypesRESULTS",
|
||||
@"id": @(oid),
|
||||
@"size": @(results->size()),
|
||||
@"schema": [self objectSchemaToJSONObject:results->object_schema]
|
||||
};
|
||||
}
|
||||
else if (RJSIsValueArray(_context, value)) {
|
||||
size_t length = RJSValidatedArrayLength(_context, jsObject);
|
||||
NSMutableArray *array = [NSMutableArray new];
|
||||
for (unsigned int i = 0; i < length; i++) {
|
||||
[array addObject:[self resultForJSValue:JSObjectGetPropertyAtIndex(_context, jsObject, i, NULL)]];
|
||||
}
|
||||
return @{@"value": array};
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary *)objectSchemaToJSONObject:(realm::ObjectSchema &)objectSchema {
|
||||
NSMutableArray *properties = [[NSMutableArray alloc] init];
|
||||
|
||||
for (realm::Property prop : objectSchema.properties) {
|
||||
NSDictionary *dict = @{
|
||||
@"name": @(prop.name.c_str()),
|
||||
@"type": @(RJSTypeGet(prop.type).c_str()),
|
||||
};
|
||||
|
||||
[properties addObject:dict];
|
||||
}
|
||||
|
||||
return @{
|
||||
@"name": @(objectSchema.name.c_str()),
|
||||
@"properties": properties,
|
||||
};
|
||||
}
|
||||
|
||||
- (JSValueRef)valueFromDictionary:(NSDictionary *)dict {
|
||||
RPCObjectID oid = [dict[@"id"] longValue];
|
||||
if (oid) {
|
||||
return _objects[oid];
|
||||
}
|
||||
|
||||
id value = dict[@"value"];
|
||||
if (!value) {
|
||||
return JSValueMakeUndefined(_context);
|
||||
}
|
||||
else if ([value isKindOfClass:[NSNull class]]) {
|
||||
return JSValueMakeNull(_context);
|
||||
}
|
||||
else if ([value isKindOfClass:[@YES class]]) {
|
||||
return JSValueMakeBoolean(_context, [value boolValue]);
|
||||
}
|
||||
else if ([value isKindOfClass:[NSNumber class]]) {
|
||||
return JSValueMakeNumber(_context, [value doubleValue]);
|
||||
}
|
||||
else if ([value isKindOfClass:[NSString class]]) {
|
||||
return RJSValueForString(_context, std::string([value UTF8String]));
|
||||
}
|
||||
else if ([value isKindOfClass:[NSArray class]]) {
|
||||
NSUInteger count = [value count];
|
||||
JSValueRef jsValues[count];
|
||||
|
||||
for (NSUInteger i = 0; i < count; i++) {
|
||||
jsValues[i] = [self valueFromDictionary:value[i]];
|
||||
}
|
||||
|
||||
return JSObjectMakeArray(_context, count, jsValues, NULL);
|
||||
}
|
||||
else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
JSObjectRef jsObject = JSObjectMake(_context, NULL, NULL);
|
||||
|
||||
for (NSString *key in value) {
|
||||
JSValueRef jsValue = [self valueFromDictionary:value[key]];
|
||||
JSStringRef jsKey = JSStringCreateWithCFString((__bridge CFStringRef)key);
|
||||
|
||||
JSObjectSetProperty(_context, jsObject, jsKey, jsValue, 0, NULL);
|
||||
JSStringRelease(jsKey);
|
||||
}
|
||||
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
return JSValueMakeUndefined(_context);
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 3c33e9f056e41adc97422c42d75d9388693e255e
|
Loading…
Reference in New Issue