mirror of
https://github.com/status-im/realm-js.git
synced 2025-01-11 06:46:03 +00:00
Add support for sync pause/resume (#2019)
* Add support for sync pause/resume * Improve the promise chain in the tests * Update CHANGELOG.md * Update sync.js
This commit is contained in:
parent
f45ba1c9e7
commit
9314ee0a7d
@ -11,6 +11,7 @@ X.Y.Z Release notes
|
|||||||
* Exposed `User.serialize` to create a persistable representation of a user instance, as well as
|
* Exposed `User.serialize` to create a persistable representation of a user instance, as well as
|
||||||
`User.deserialize` to later inflate a `User` instance that can be used to connect to Realm Object
|
`User.deserialize` to later inflate a `User` instance that can be used to connect to Realm Object
|
||||||
Server and open synchronized Realms (#1276).
|
Server and open synchronized Realms (#1276).
|
||||||
|
* Added `Session.start()` and `Session.stop()` in order to allow stopping to sync data (#2014).
|
||||||
* Added support for `LIMIT` in queries to restrict the size of the results set. This is in particular useful for query-based synced Realms. An example of the syntax is `age >= 20 LIMIT(2)`.
|
* Added support for `LIMIT` in queries to restrict the size of the results set. This is in particular useful for query-based synced Realms. An example of the syntax is `age >= 20 LIMIT(2)`.
|
||||||
|
|
||||||
### Bug fixes
|
### Bug fixes
|
||||||
|
20
docs/sync.js
20
docs/sync.js
@ -651,6 +651,26 @@ class Session {
|
|||||||
*/
|
*/
|
||||||
isConnected() {}
|
isConnected() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a sync session.
|
||||||
|
*
|
||||||
|
* This method is asynchronous so in order to know when the session has started you will need
|
||||||
|
* to add a connection notification with `addConnectionNotification`.
|
||||||
|
*
|
||||||
|
* This method is idempotent so it will be a no-op if the session has already started.
|
||||||
|
*/
|
||||||
|
start() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops a sync session.
|
||||||
|
*
|
||||||
|
* This method is asynchronous so in order to know when the session has started you will need
|
||||||
|
* to add a connection notification with `addConnectionNotification`.
|
||||||
|
*
|
||||||
|
* This method is idempotent so it will be a no-op if the session has already stopped.
|
||||||
|
*/
|
||||||
|
stop() {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,6 +39,8 @@ createMethods(Session.prototype, objectTypes.SESSION, [
|
|||||||
'addConnectionNotification',
|
'addConnectionNotification',
|
||||||
'removeConnectionNotification',
|
'removeConnectionNotification',
|
||||||
'isConnected',
|
'isConnected',
|
||||||
|
'start',
|
||||||
|
'stop',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export function createSession(realmId, info) {
|
export function createSession(realmId, info) {
|
||||||
|
3
lib/index.d.ts
vendored
3
lib/index.d.ts
vendored
@ -470,6 +470,9 @@ declare namespace Realm.Sync {
|
|||||||
removeConnectionNotification(callback: ConnectionNotificationCallback): void;
|
removeConnectionNotification(callback: ConnectionNotificationCallback): void;
|
||||||
|
|
||||||
isConnected(): boolean;
|
isConnected(): boolean;
|
||||||
|
|
||||||
|
start(): void;
|
||||||
|
stop(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubscriptionNotificationCallback = (subscription: Subscription, state: number) => void;
|
type SubscriptionNotificationCallback = (subscription: Subscription, state: number) => void;
|
||||||
|
@ -233,6 +233,8 @@ public:
|
|||||||
static void add_connection_notification(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &);
|
static void add_connection_notification(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &);
|
||||||
static void remove_connection_notification(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &);
|
static void remove_connection_notification(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &);
|
||||||
static void is_connected(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &);
|
static void is_connected(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &);
|
||||||
|
static void start(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &);
|
||||||
|
static void stop(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &);
|
||||||
|
|
||||||
|
|
||||||
static void override_server(ContextType ctx, ObjectType this_object, Arguments args, ReturnValue&);
|
static void override_server(ContextType ctx, ObjectType this_object, Arguments args, ReturnValue&);
|
||||||
@ -254,6 +256,8 @@ public:
|
|||||||
{"addConnectionNotification", wrap<add_connection_notification>},
|
{"addConnectionNotification", wrap<add_connection_notification>},
|
||||||
{"removeConnectionNotification", wrap<remove_connection_notification>},
|
{"removeConnectionNotification", wrap<remove_connection_notification>},
|
||||||
{"isConnected", wrap<is_connected>},
|
{"isConnected", wrap<is_connected>},
|
||||||
|
{"start", wrap<start>},
|
||||||
|
{"stop", wrap<stop>},
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -646,6 +650,24 @@ void SessionClass<T>::is_connected(ContextType ctx, FunctionType, ObjectType thi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SessionClass<T>::start(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||||
|
validate_argument_count(argc, 0);
|
||||||
|
return_value.set(false);
|
||||||
|
if (auto session = get_internal<T, SessionClass<T>>(this_object)->lock()) {
|
||||||
|
session->revive_if_needed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SessionClass<T>::stop(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) {
|
||||||
|
validate_argument_count(argc, 0);
|
||||||
|
return_value.set(false);
|
||||||
|
if (auto session = get_internal<T, SessionClass<T>>(this_object)->lock()) {
|
||||||
|
session->log_out();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void SessionClass<T>::override_server(ContextType ctx, ObjectType this_object, Arguments args, ReturnValue&) {
|
void SessionClass<T>::override_server(ContextType ctx, ObjectType this_object, Arguments args, ReturnValue&) {
|
||||||
args.validate_count(2);
|
args.validate_count(2);
|
||||||
|
@ -84,6 +84,16 @@ function runOutOfProcess() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function waitForSessionConnected(session) {
|
||||||
|
return new Promise(res => {
|
||||||
|
session.addConnectionNotification((newState, oldState) => {
|
||||||
|
if (newState === Realm.Sync.ConnectionState.Connected) {
|
||||||
|
res();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
testLocalRealmHasNoSession() {
|
testLocalRealmHasNoSession() {
|
||||||
let realm = new Realm();
|
let realm = new Realm();
|
||||||
@ -1041,11 +1051,121 @@ module.exports = {
|
|||||||
resolve('Done');
|
resolve('Done');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
setTimeout(() => { reject() }, 10000);
|
||||||
}).catch(error => reject(error));
|
}).catch(error => reject(error));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
testStartStop() {
|
||||||
|
if(!isNodeProccess) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password')
|
||||||
|
.then((user) => {
|
||||||
|
const config = {
|
||||||
|
sync: {
|
||||||
|
user: user,
|
||||||
|
url: `realm://localhost:9080/~/${uuid()}`,
|
||||||
|
fullSynchronization: true,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Realm.open(config);
|
||||||
|
}).then((realm) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const session = realm.syncSession;
|
||||||
|
|
||||||
|
const checks = {
|
||||||
|
started: false,
|
||||||
|
stopped: false,
|
||||||
|
restarted: false
|
||||||
|
}
|
||||||
|
|
||||||
|
session.addConnectionNotification((newState, oldState) => {
|
||||||
|
if (newState === Realm.Sync.ConnectionState.Connected && checks.started === false) { checks.started = true; session.stop(); }
|
||||||
|
if (newState === Realm.Sync.ConnectionState.Connected && checks.started === true) { checks.restarted = true; resolve(); }
|
||||||
|
if (newState === Realm.Sync.ConnectionState.Disconnected) { checks.stopped = true; session.start();}
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => { reject("Timeout") }, 10000);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
testMultipleStarts() {
|
||||||
|
if(!isNodeProccess) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password')
|
||||||
|
.then((user) => {
|
||||||
|
const config = {
|
||||||
|
sync: {
|
||||||
|
user: user,
|
||||||
|
url: `realm://localhost:9080/~/${uuid()}`,
|
||||||
|
fullSynchronization: true,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Realm.open(config)
|
||||||
|
}).then(realm => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const session = realm.syncSession;
|
||||||
|
|
||||||
|
waitForSessionConnected(session).then(() => {
|
||||||
|
session.start();
|
||||||
|
session.start();
|
||||||
|
session.start();
|
||||||
|
setTimeout(() => {
|
||||||
|
if (session.isConnected()) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
testMultipleStopped() {
|
||||||
|
if(!isNodeProccess) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Realm.Sync.User.register('http://localhost:9080', uuid(), 'password')
|
||||||
|
.then((user) => {
|
||||||
|
const config = {
|
||||||
|
sync: {
|
||||||
|
user: user,
|
||||||
|
url: `realm://localhost:9080/~/${uuid()}`,
|
||||||
|
fullSynchronization: true,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Realm.open(config)
|
||||||
|
}).then(realm => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const session = realm.syncSession;
|
||||||
|
|
||||||
|
waitForSessionConnected(session).then(() => {
|
||||||
|
session.stop();
|
||||||
|
session.stop();
|
||||||
|
session.stop();
|
||||||
|
setTimeout(() => {
|
||||||
|
if (session.isConnected()) {
|
||||||
|
reject();
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
testOfflinePermissionSchemas() {
|
testOfflinePermissionSchemas() {
|
||||||
if (!isNodeProccess) {
|
if (!isNodeProccess) {
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user