realm
Version:
Realm by MongoDB is an offline-first mobile database: an alternative to SQLite and key-value stores
235 lines • 9.95 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.BaseSubscriptionSet = exports.SubscriptionsState = exports.SubscriptionSetState = void 0;
const internal_1 = require("../internal");
/**
* Enum representing the state of a {@link SubscriptionSet}.
*/
var SubscriptionSetState;
(function (SubscriptionSetState) {
/**
* The subscription update has been persisted locally, but the server hasn't
* yet returned all the data that matched the updated subscription queries.
*/
SubscriptionSetState["Pending"] = "pending";
/**
* The server has acknowledged the subscription and sent all the data that
* matched the subscription queries at the time the SubscriptionSet was
* updated. The server is now in steady-state synchronization mode where it
* will stream updates as they come.
*/
SubscriptionSetState["Complete"] = "complete";
/**
* The server has returned an error and synchronization is paused for this
* Realm. To view the actual error, use `Subscriptions.error`.
*
* You can still use {@link SubscriptionSet.update} to update the subscriptions,
* and if the new update doesn't trigger an error, synchronization will be restarted.
*/
SubscriptionSetState["Error"] = "error";
/**
* The SubscriptionSet has been superseded by an updated one. This typically means
* that someone has called {@link SubscriptionSet.update} on a different instance
* of the {@link SubscriptionSet}. You should not use a superseded SubscriptionSet,
* and instead obtain a new instance from {@link Realm.subscriptions}.
*/
SubscriptionSetState["Superseded"] = "superseded";
})(SubscriptionSetState = exports.SubscriptionSetState || (exports.SubscriptionSetState = {}));
/**
* @deprecated Will be removed in v13.0.0. Please use {@link SubscriptionSetState}.
*/
var SubscriptionsState;
(function (SubscriptionsState) {
/**
* The subscription update has been persisted locally, but the server hasn't
* yet returned all the data that matched the updated subscription queries.
*/
SubscriptionsState["Pending"] = "pending";
/**
* The server has acknowledged the subscription and sent all the data that
* matched the subscription queries at the time the SubscriptionSet was
* updated. The server is now in steady-state synchronization mode where it
* will stream updates as they come.
*/
SubscriptionsState["Complete"] = "complete";
/**
* The server has returned an error and synchronization is paused for this
* Realm. To view the actual error, use `Subscriptions.error`.
*
* You can still use {@link SubscriptionSet.update} to update the subscriptions,
* and if the new update doesn't trigger an error, synchronization will be restarted.
*/
SubscriptionsState["Error"] = "error";
/**
* The SubscriptionSet has been superseded by an updated one. This typically means
* that someone has called {@link SubscriptionSet.update} on a different instance
* of the {@link SubscriptionSet}. You should not use a superseded SubscriptionSet,
* and instead obtain a new instance from {@link Realm.subscriptions}.
*/
SubscriptionsState["Superseded"] = "superseded";
})(SubscriptionsState = exports.SubscriptionsState || (exports.SubscriptionsState = {}));
const DEFAULT_PROPERTY_DESCRIPTOR = { configurable: true, enumerable: true, writable: false };
const PROXY_HANDLER = {
ownKeys(target) {
return Reflect.ownKeys(target).concat([...target.keys()].map(String));
},
getOwnPropertyDescriptor(target, prop) {
if (Reflect.has(target, prop)) {
return Reflect.getOwnPropertyDescriptor(target, prop);
}
if (typeof prop === "string") {
const BASE = 10;
const index = Number.parseInt(prop, BASE);
if (index >= 0 && index < target.length) {
return DEFAULT_PROPERTY_DESCRIPTOR;
}
}
},
// Not defining `set()` here will make e.g. `mySubscriptions[0] = someValue` a no-op
// if strict mode (`"use strict"`) is used, or throw a TypeError if it is not used.
};
/**
* Class representing the common functionality for the {@link SubscriptionSet} and
* {@link MutableSubscriptionSet} classes.
*
* SubscriptionSets can only be modified inside a {@link SubscriptionSet.update} callback.
*
* The SubscriptionSet is an iterable; thus, the contained {@link Subscription}s can be
* accessed in `for-of` loops or spread into an `Array` for access to the ECMAScript
* Array API, e.g. `[...realm.subscriptions][0]`.
*/
class BaseSubscriptionSet {
internal;
/** @internal */
constructor(/** @internal */ internal) {
this.internal = internal;
Object.defineProperty(this, "internal", {
enumerable: false,
configurable: false,
// `internal` needs to be writable due to `SubscriptionSet.updateNoWait()`
// overwriting `this.internal` with the new committed set.
writable: true,
});
return new Proxy(this, PROXY_HANDLER);
}
/**
* Whether there are no subscriptions in the set.
* @returns `true` if there are no subscriptions in the set, `false` otherwise.
*/
get isEmpty() {
return this.internal.size === 0;
}
/**
* The version of the SubscriptionSet. This is incremented every time a
* {@link SubscriptionSet.update} is applied.
* @returns The version of the {@link SubscriptionSet}.
*/
get version() {
return Number(this.internal.version);
}
/**
* @returns The state of the SubscriptionSet.
*/
get state() {
const state = this.internal.state;
switch (state) {
case 0 /* binding.SyncSubscriptionSetState.Uncommitted */:
case 1 /* binding.SyncSubscriptionSetState.Pending */:
case 2 /* binding.SyncSubscriptionSetState.Bootstrapping */:
case 6 /* binding.SyncSubscriptionSetState.AwaitingMark */:
return SubscriptionSetState.Pending;
case 3 /* binding.SyncSubscriptionSetState.Complete */:
return SubscriptionSetState.Complete;
case 4 /* binding.SyncSubscriptionSetState.Error */:
return SubscriptionSetState.Error;
case 5 /* binding.SyncSubscriptionSetState.Superseded */:
return SubscriptionSetState.Superseded;
default:
throw new Error(`Unsupported SubscriptionSetState value: ${state}`);
}
}
/**
* If `state` is {@link SubscriptionSetState.Error}, this will be a string representing
* why the {@link SubscriptionSet} is in an error state. It will be `null` if there is no error.
* @returns A string representing the error, or `null` if there is no error.
*/
get error() {
return this.state === SubscriptionSetState.Error ? this.internal.errorStr : null;
}
/**
* @returns The number of subscriptions in the set.
*/
get length() {
return this.internal.size;
}
/**
* Find a subscription by name.
* @param name - The name to search for.
* @returns The named subscription, or `null` if the subscription is not found.
*/
findByName(name) {
internal_1.assert.string(name, "name");
const subscription = this.internal.findByName(name);
return subscription ? new internal_1.Subscription(subscription) : null;
}
/**
* Find a subscription by query. Will match both named and unnamed subscriptions.
* @param query - The query to search for, represented as a {@link Results} instance,
* e.g. `Realm.objects("Cat").filtered("age > 10")`.
* @returns The subscription with the specified query, or `null` if the subscription is not found.
*/
findByQuery(query) {
internal_1.assert.instanceOf(query, internal_1.Results, "query");
const subscription = this.internal.findByQuery(query.internal.query);
return subscription ? new internal_1.Subscription(subscription) : null; // TODO: Remove the type assertion into Subscription
}
/** @internal */
exists(query) {
if (query.subscriptionName === undefined) {
return !!this.internal.findByQuery(query.internal.query);
}
return !!this.internal.findByName(query.subscriptionName);
}
/**
* Makes the subscription set iterable.
* @returns Iterable of each value in the set.
* @example
* for (const subscription of subscriptions) {
* // ...
* }
*/
*[Symbol.iterator]() {
for (const subscription of this.internal) {
yield new internal_1.Subscription(subscription);
}
}
/**
* Get an iterator that contains each index in the subscription set.
* @internal
*/
*keys() {
const size = this.length;
for (let i = 0; i < size; i++) {
yield i;
}
}
}
exports.BaseSubscriptionSet = BaseSubscriptionSet;
//# sourceMappingURL=BaseSubscriptionSet.js.map