Merge remote-tracking branch 'origin/master' into tg/object-accessor-updates

This commit is contained in:
Mark Rowe 2017-05-22 14:39:55 -07:00
commit 66da78af74
8 changed files with 259 additions and 11 deletions

View File

@ -1,10 +1,10 @@
vnext 1.3.1 Release notes (2017-5-18)
============================================================= =============================================================
### Breaking changes ### Breaking changes
* None * None
### Enhancements ### Enhancements
* None * Add Realm open async API support.
### Bug fixes ### Bug fixes
* None * None
@ -19,7 +19,7 @@ Old files can still be opened and files open in read-only mode will not be modif
* The SyncConfig now gets two more optional parameters, `validate_ssl` and `ssl_trust_certificate_path`. * The SyncConfig now gets two more optional parameters, `validate_ssl` and `ssl_trust_certificate_path`.
### Enhancements ### Enhancements
* Add Realm open async API support. * None
### Bug fixes ### Bug fixes
* None * None

View File

@ -1,5 +1,5 @@
PACKAGE_NAME=realm-js PACKAGE_NAME=realm-js
VERSION=1.3.0 VERSION=1.3.1
REALM_CORE_VERSION=2.7.0 REALM_CORE_VERSION=2.7.0
REALM_SYNC_VERSION=1.8.4 REALM_SYNC_VERSION=1.8.4
REALM_OBJECT_SERVER_VERSION=1.3.0 REALM_OBJECT_SERVER_VERSION=1.3.0

View File

@ -75,6 +75,23 @@ class Realm {
*/ */
constructor(config) {} constructor(config) {}
/**
* Open a realm asynchronously with a promise. If the realm is synced, it will be fully
* synchronized before it is available.
* @param {Realm~Configuration} config
* @returns {Promise} - a promise that will be resolved with the realm instance when it's available.
*/
static open(config) {}
/**
* Open a realm asynchronously with a callback. If the realm is synced, it will be fully
* synchronized before it is available.
* @param {Realm~Configuration} config
* @param {function(error, realm)} callback - will be called when the realm is ready.
* @throws {Error} If anything in the provided `config` is invalid.
*/
static openAsync(config, callback) {}
/** /**
* Closes this Realm so it may be re-opened with a newer schema version. * Closes this Realm so it may be re-opened with a newer schema version.
* All objects and collections from this Realm are no longer valid after calling this method. * All objects and collections from this Realm are no longer valid after calling this method.

View File

@ -264,3 +264,104 @@ class Session {
*/ */
get state() {} get state() {}
} }
/**
* Class for creating custom Data Connectors. Only available in the Enterprise Edition.
* @memberof Realm.Sync
*/
class Adapter {
/**
* Create a new Adapter to moitor and process changes made across multiple Realms
* @param {string} local_path - the local path where realm files are stored
* @param {string} server_url - the sync server to listen to
* @param {SyncUser} admin_user - an admin user obtained by calling `new Realm.Sync.User.adminUser`
* @param {string} regex - a regular expression used to determine which cahnged Realms should be monitored -
* use `.*` to match all all Realms
* @param {function(realm_path)} change_callback - called when a new transaction is available
* to process for the given realm_path
*/
constructor(local_path, server_url, admin_user, regex, change_callback) {}
/**
* Get the Array of current instructions for the given Realm.
* @param {string} path - the path for the Realm being monitored
* @returns {Array(instructions)} or {undefined} if all transactions have been processed
*/
current(path) {}
/**
* Advance the to the next transaction indicating that you are done processing the current
* instructions for the given Realm.
* @param {string} path - the path for the Realm to advance
*/
advance(path) {}
/**
* Open the Realm used by the Adapter for the given path. This is useful for writing two way
* adapters as transactions written to this realm will be ignored when calling `current` and `advance`
* @param {string} path - the path for the Realm to open
* @returns {Realm}
*/
realmAtPath(path) {}
/**
* Close the adapter and all opened Realms.
*/
close() {}
}
/**
* The following Instructions can be returned by `Adapter.current(path)`. Each instruction object has
* a `type` property which is one of the following types. For each type below we list the other properties
* that will exist in the instruction object.
* @typedef Realm.Sync.Adapter~Instruction
* @type {(INSERT|SET|DELETE|CLEAR|CHANGE_IDENTITY|LIST_SET|LIST_INSERT|LIST_ERASE|LIST_CLEAR|ADD_TYPE|ADD_PROPERTY)}
* @property INSERT - insert a new object
* - `object_type` - type of the object being inserted
* - `identity` - primary key value or row index for the object
* - `values` - map of property names and property values for the object to insert
* @property SET - set property values for an existing object
* - `object_type` - type of the object
* - `identity` - primary key value or row index for the object
* - `values` - map of property names and property values to update for the object
* @property DELETE - delete an exising object
* - `object_type` - type of the object
* - `identity` - primary key value or row index for the object
* @property CLEAR - delete all objects of a given type
* - `object_type` - type of the object
* @property LIST_SET - set the object at a given list index to an object
* - `object_type` - type of the object
* - `identity` - primary key for the object
* - `property` - property name for the list property to mutate
* - `list_index` - list index to set
* - `object_identity` - primary key or row number of the object being set
* @property LIST_INSERT - insert an object in the list at the given index
* - `object_type` - type of the object
* - `identity` - primary key for the object
* - `property` - property name for the list property to mutate
* - `list_index` - list index at which to insert
* - `object_identity` - primary key or row number of the object to insert
* @property LIST_ERASE - erase an object in the list at the given index - this removes the object
* from the list but the object will still exist in the Realm
* - `object_type` - type of the object
* - `identity` - primary key for the object
* - `property` - property name for the list property to mutate
* - `list_index` - list index which should be erased
* @property LIST_CLEAR - clear a list removing all objects - objects are not deleted from the Realm
* - `object_type` - type of the object
* - `identity` - primary key for the object
* - `property` - property name for the list property to clear
* @property ADD_TYPE - add a new type
* - `object_type` - name of the type
* - `primary_key` - name of primary key property for this type
* - `properties` - Property map as described in {@link Realm~ObjectSchema}
* @property ADD_PROPERTIES - add properties to an existing type
* - `object_type` - name of the type
* - `properties` - Property map as described in {@link Realm~ObjectSchema}
* @property CHANGE_IDENTITY - change the row index for an existing object - not called for objects
* with primary keys
* - `object_type` - type fo the object
* - `identity` - old row value for the object
* - `new_identity` - new row value for the object
*/

View File

@ -175,6 +175,11 @@ Object.defineProperties(Realm, {
rpc.clearTestState(); rpc.clearTestState();
}, },
}, },
_waitForDownload: {
value: function(_config, callback) {
callback();
}
},
}); });
for (let i = 0, len = debugHosts.length; i < len; i++) { for (let i = 0, len = debugHosts.length; i < len; i++) {

View File

@ -1,7 +1,7 @@
{ {
"name": "realm", "name": "realm",
"description": "Realm is a mobile database: an alternative to SQLite and key-value stores", "description": "Realm is a mobile database: an alternative to SQLite and key-value stores",
"version": "1.3.0", "version": "1.3.1",
"license": "Apache-2.0", "license": "Apache-2.0",
"homepage": "https://realm.io", "homepage": "https://realm.io",
"keywords": [ "keywords": [
@ -46,8 +46,6 @@
"scripts": { "scripts": {
"get-version": "node -p process.env.npm_package_version", "get-version": "node -p process.env.npm_package_version",
"set-version": "scripts/set-version.sh", "set-version": "scripts/set-version.sh",
"get-core-version": "env-cmd ./dependencies.list node -p process.env.REALM_CORE_VERSION",
"get-sync-version": "env-cmd ./dependencies.list node -p process.env.REALM_SYNC_VERSION",
"lint": "eslint", "lint": "eslint",
"test": "scripts/test.sh", "test": "scripts/test.sh",
"install": "node-pre-gyp install --fallback-to-build", "install": "node-pre-gyp install --fallback-to-build",
@ -89,7 +87,6 @@
}, },
"devDependencies": { "devDependencies": {
"babel-eslint": "^6.0.4", "babel-eslint": "^6.0.4",
"env-cmd": "^5.0.0",
"eslint": "^3.2.2", "eslint": "^3.2.2",
"eslint-plugin-jasmine": "^2.1.0", "eslint-plugin-jasmine": "^2.1.0",
"eslint-plugin-react": "^6.7.0", "eslint-plugin-react": "^6.7.0",

View File

@ -956,7 +956,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1.3.0; CURRENT_PROJECT_VERSION = 1.3.1;
CXX = "$(SRCROOT)/../scripts/ccache-clang++.sh"; CXX = "$(SRCROOT)/../scripts/ccache-clang++.sh";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
@ -1020,7 +1020,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1.3.0; CURRENT_PROJECT_VERSION = 1.3.1;
CXX = "$(SRCROOT)/../scripts/ccache-clang++.sh"; CXX = "$(SRCROOT)/../scripts/ccache-clang++.sh";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO; ENABLE_NS_ASSERTIONS = NO;

View File

@ -234,6 +234,134 @@ module.exports = {
}); });
}, },
testRealmOpenAsyncNoSchema() {
if (!isNodeProccess) {
return Promise.resolve();
}
const username = uuid();
const realmName = uuid();
const expectedObjectsCount = 3;
let tmpDir = tmp.dirSync();
let content = fs.readFileSync(__dirname + '/download-api-helper.js', 'utf8');
let tmpFile = tmp.fileSync({ dir: tmpDir.name });
fs.appendFileSync(tmpFile.fd, content, { encoding: 'utf8' });
return new Promise((resolve, reject) => {
//execute download-api-helper which inserts predefined number of objects into the synced realm.
const child = execFile('node', [tmpFile.name, username, realmName, REALM_MODULE_PATH], { cwd: tmpDir.name }, (error, stdout, stderr) => {
if (error) {
reject(new Error('Error executing download api helper' + error));
}
resolve();
});
})
.then(() => {
return promisifiedLogin('http://localhost:9080', username, 'password').then(user => {
return new Promise((resolve, reject) => {
const accessTokenRefreshed = this;
let successCounter = 0;
let config = {
sync: { user, url: `realm://localhost:9080/~/${realmName}` }
};
Realm.openAsync(config, (error, realm) => {
try {
if (error) {
reject(error);
}
let actualObjectsCount = realm.objects('Dog').length;
TestCase.assertEqual(actualObjectsCount, expectedObjectsCount, "Synced realm does not contain the expected objects count");
let firstDog = realm.objects('Dog')[0];
TestCase.assertTrue(({}).hasOwnProperty.call(firstDog, 'name'), "Synced realm does not have an inffered schema");
TestCase.assertTrue(firstDog.name, "Synced realm object's property should have a value");
TestCase.assertTrue(firstDog.name.indexOf('Lassy') !== -1, "Synced realm object's property should contain the actual written value");
const session = realm.syncSession;
TestCase.assertInstanceOf(session, Realm.Sync.Session);
TestCase.assertEqual(session.user.identity, user.identity);
TestCase.assertEqual(session.config.url, config.sync.url);
TestCase.assertEqual(session.config.user.identity, config.sync.user.identity);
TestCase.assertEqual(session.state, 'active');
resolve();
}
catch (e) {
reject(e);
}
});
});
});
});
},
testRealmOpenLocalRealm() {
const username = uuid();
const expectedObjectsCount = 3;
return new Promise((resolve, reject) => {
const accessTokenRefreshed = this;
let successCounter = 0;
let config = {
schema: [{ name: 'Dog', properties: { name: 'string' } }],
};
Realm.open(config).then(realm => {
realm.write(() => {
for (let i = 1; i <= 3; i++) {
realm.create('Dog', { name: `Lassy ${i}` });
}
});
let actualObjectsCount = realm.objects('Dog').length;
TestCase.assertEqual(actualObjectsCount, expectedObjectsCount, "Local realm does not contain the expected objects count");
resolve();
}).catch(error => reject(error));
});
},
testRealmOpenAsyncLocalRealm() {
const username = uuid();
const expectedObjectsCount = 3;
return new Promise((resolve, reject) => {
const accessTokenRefreshed = this;
let successCounter = 0;
let config = {
schema: [{ name: 'Dog', properties: { name: 'string' } }],
};
Realm.openAsync(config, (error, realm) => {
try {
if (error) {
reject(error);
}
realm.write(() => {
for (let i = 1; i <= 3; i++) {
realm.create('Dog', { name: `Lassy ${i}` });
}
});
let actualObjectsCount = realm.objects('Dog').length;
TestCase.assertEqual(actualObjectsCount, expectedObjectsCount, "Local realm does not contain the expected objects count");
resolve();
}
catch (e) {
reject(e);
}
});
});
},
testErrorHandling() { testErrorHandling() {
return promisifiedRegister('http://localhost:9080', uuid(), 'password').then(user => { return promisifiedRegister('http://localhost:9080', uuid(), 'password').then(user => {
return new Promise((resolve, _reject) => { return new Promise((resolve, _reject) => {