@react-native-ohos/realm
Version:
Realm by MongoDB is an offline-first mobile database: an alternative to SQLite and key-value stores
176 lines • 8.03 kB
JavaScript
;
////////////////////////////////////////////////////////////////////////////
//
// Copyright 2023 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.
//
////////////////////////////////////////////////////////////////////////////
Object.defineProperty(exports, "__esModule", { value: true });
exports.MutableSubscriptionSet = exports.WaitForSync = void 0;
const binding_1 = require("../binding");
const assert_1 = require("../assert");
const indirect_1 = require("../indirect");
const BaseSubscriptionSet_1 = require("./BaseSubscriptionSet");
const Subscription_1 = require("./Subscription");
/**
* Behavior when waiting for subscribed objects to be synchronized/downloaded.
*/
var WaitForSync;
(function (WaitForSync) {
/**
* Waits until the objects have been downloaded from the server
* the first time the subscription is created. If the subscription
* already exists, the `Results` is returned immediately.
*/
WaitForSync["FirstTime"] = "first-time";
/**
* Always waits until the objects have been downloaded from the server.
*/
WaitForSync["Always"] = "always";
/**
* Never waits for the download to complete, but keeps downloading the
* objects in the background.
*/
WaitForSync["Never"] = "never";
})(WaitForSync = exports.WaitForSync || (exports.WaitForSync = {}));
/**
* The mutable version of a given SubscriptionSet. The {@link MutableSubscriptionSet}
* instance can only be used from inside the {@link SubscriptionSet.update} callback.
*/
class MutableSubscriptionSet extends BaseSubscriptionSet_1.BaseSubscriptionSet {
/** @internal */
constructor(/** @internal */ internal) {
super(internal);
}
/**
* Add a query to the set of active subscriptions. The query will be joined via
* an `OR` operator with any existing queries for the same type.
*
* A query is represented by a {@link Results} instance returned from {@link Realm.objects},
* for example: `mutableSubs.add(realm.objects("Cat").filtered("age > 10"));`.
* @param query - A {@link Results} instance representing the query to subscribe to.
* @param options - An optional {@link SubscriptionOptions} object containing options to
* use when adding this subscription (e.g. to give the subscription a name).
* @returns A `Subscription` instance for the new subscription.
*/
add(query, options) {
assert_1.assert.instanceOf(query, indirect_1.indirect.Results, "query");
if (options) {
validateSubscriptionOptions(options);
}
const subscriptions = this.internal;
const results = query.internal;
const queryInternal = results.query;
if (options?.throwOnUpdate && options.name !== undefined) {
const existingSubscription = subscriptions.findByName(options.name);
if (existingSubscription) {
const isSameQuery = existingSubscription.queryString === queryInternal.description &&
existingSubscription.objectClassName === results.objectType;
(0, assert_1.assert)(isSameQuery, `A subscription with the name '${options.name}' already exists but has a different query. If you meant to update it, remove 'throwOnUpdate: true' from the subscription options.`);
}
}
const [subscription] =
// Check for `undefined` rather than falsy since we treat empty names as named.
options?.name === undefined
? subscriptions.insertOrAssignByQuery(queryInternal)
: subscriptions.insertOrAssignByName(options.name, queryInternal);
query.subscriptionName = subscription.name;
return new Subscription_1.Subscription(subscription);
}
/**
* Remove a subscription with the given query from the SubscriptionSet.
* @param query - A {@link Results} instance representing the query to remove a subscription to.
* @returns `true` if the subscription was removed, `false` if it was not found.
*/
remove(query) {
assert_1.assert.instanceOf(query, indirect_1.indirect.Results, "query");
return this.internal.eraseByQuery(query.internal.query);
}
/**
* Remove a subscription with the given name from the SubscriptionSet.
* @param name - The name of the subscription to remove.
* @returns `true` if the subscription was removed, `false` if it was not found.
*/
removeByName(name) {
assert_1.assert.string(name, "name");
return this.internal.eraseByName(name);
}
/**
* Remove the specified subscription from the SubscriptionSet.
* @param subscription - The {@link Subscription} instance to remove.
* @returns `true` if the subscription was removed, `false` if it was not found.
*/
removeSubscription(subscription) {
assert_1.assert.instanceOf(subscription, Subscription_1.Subscription, "subscription");
return binding_1.binding.Helpers.eraseSubscription(this.internal, subscription.internal);
}
/**
* Remove all subscriptions for the specified object type from the SubscriptionSet.
* @param objectType - The string name of the object type to remove all subscriptions for.
* @returns The number of subscriptions removed.
*/
removeByObjectType(objectType) {
assert_1.assert.string(objectType, "objectType");
return this.removeByPredicate((subscription) => subscription.objectClassName === objectType);
}
/**
* Remove all subscriptions from the SubscriptionSet.
* @returns The number of subscriptions removed.
*/
removeAll() {
const numRemoved = this.internal.size;
this.internal.clear();
return numRemoved;
}
/**
* Remove all unnamed/anonymous subscriptions from the SubscriptionSet.
* @returns The number of subscriptions removed.
*/
removeUnnamed() {
return this.removeByPredicate((subscription) => subscription.name === undefined);
}
/** @internal */
removeByPredicate(predicate) {
// TODO: This is currently O(n^2) because each erase call is O(n). Once Core has
// fixed https://github.com/realm/realm-core/issues/6241, we can update this.
// Removing the subscription (calling `eraseSubscription()`) invalidates all current
// iterators, so it would be illegal to continue iterating. Instead, we push it to an
// array to remove later.
const subscriptionsToRemove = [];
for (const subscription of this.internal) {
if (predicate(subscription)) {
subscriptionsToRemove.push(subscription);
}
}
let numRemoved = 0;
for (const subscription of subscriptionsToRemove) {
const isRemoved = binding_1.binding.Helpers.eraseSubscription(this.internal, subscription);
if (isRemoved) {
numRemoved++;
}
}
return numRemoved;
}
}
exports.MutableSubscriptionSet = MutableSubscriptionSet;
function validateSubscriptionOptions(input) {
assert_1.assert.object(input, "options", { allowArrays: false });
if (input.name !== undefined) {
assert_1.assert.string(input.name, "'name' on 'SubscriptionOptions'");
}
if (input.throwOnUpdate !== undefined) {
assert_1.assert.boolean(input.throwOnUpdate, "'throwOnUpdate' on 'SubscriptionOptions'");
}
}
//# sourceMappingURL=MutableSubscriptionSet.js.map