Changelog
12.2.0 (2023-09-24)
Realm.App.Sync.reconnect(app)
has been deprecated and will be removed in the next major version. You can use Realm.App.Sync.Session.reconnect()
instead.Realm.Sync.Session.reconnect()
to help force a reconnection to Atlas Device Sync. (#6123)Realm.App.AppConfiguration.metaData
which will make it possible to encrypt metadata used by the Realm.App
. (#6147)Realm.schemaVersion
wasn't propagated correctly for non-existing files. (#6119, since v12.0.0)description TEXT 'alex*'
. (realm/realm-core#6860)GEOWITHIN
queries. (realm/realm-core#6934)Assertion failed: ref + size <= next->first
. (realm/realm-core#6340, since v11.3.0)Bad server version
errors and client reset which sometimes occurred when updating a subscription's query. (realm/realm-core#6966, since v10.12.0)Changelog
12.1.0 (2023-08-30)
migrationOptions.resolveEmbeddedConstraints
to support for automatic resolution of embedded object constraints during migration. (#6073)GLIBC_2.34' not found (required by /home/user/MyProject/node_modules/realm/generated/ts/realm.node)
could be observed. (#6082, since v12.0.0)Realm.Object.linkingObjects()
when the origin and target are of different object types. (#6108, since v12.0.0)Realm.Configuration
. (#6081, since v12.0.0)Changelog
12.0.0 (2023-08-17)
NOTE: This combines all changelog entries for prereleases of v12.0.0.
Although this is a complete rewrite of our SDK, we've strived to keep breakages to a minimum and expect our users to upgrade from v11 without any significant changes to their code-base.
Realm.BSON
, to simplify the new SDK we want to export only the BSON types that our SDK database component supports (ObjectId, Decimal128 and UUID). See #4934.Realm.Object
via the standard Object.keys(obj)
. As a side-effect we stopped supporting the object spread operator {...obj}
and introduced Realm.Object#keys()
, Realm.Object#entries()
and Realm.Object#toJSON()
methods were introduced as a workaround. The new SDK wraps its accessor objects in a Proxy trapping the ownKeys operation which enables calls to the standard Object.keys(obj)
and the spread operator {...obj}
to work correctly, with minimal performance impact on normal accesses. Therefore, we are deprecating the APIs with the @deprecation annotation and a console.warn
when calling RealmObject#keys()
and RealmObject#entries()
. RealmObject#toJSON
still serves the purpose of producing a circularly referencing object graph. We would love the community's feedback on this!Results
, List
and Set
used to inherit directly from Collection
but now inherits from an abstract OrderedCollection
, which extends Collection
.PropertySchema
and PropertySchemaShorthand
types.)// Example object schema
const TaskSchema = {
name: "Task",
properties: {
description: /* property schema (shorthand or object form) */,
},
};
// Explicitness
"[]" // Bad (previously parsed as implicit "mixed")
"mixed[]" // Good
{ type: "list" } // Bad
{ type: "list", objectType: "mixed" } // Good
// Mixing shorthand and object form
{ type: "int[]" } // Bad
"int[]" // Good
{ type: "list", objectType: "int" } // Good
{ type: "int?" } // Bad
"int?" // Good
{ type: "int", optional: true } // Good
// Specifying object types
{ type: "SomeType" } // Bad
"SomeType" // Good
{ type: "object", objectType: "SomeType" } // Good
{ type: "object[]", objectType: "SomeType" } // Bad
"SomeType[]" // Good
{ type: "list", objectType: "SomeType" } // Good
{ type: "linkingObjects", objectType: "SomeType", property: "someProperty" } // Good
instanceof SomeClass
checks, however, code which is directly using prototype or constructor comparisons will fail:Object.getPrototypeOf(object) == CustomObject.prototype // No longer works
object.constructor == CustomObject // No longer works
Symbol
type). In the new SDK, using a Symbol as a key in a dictionary will throw.SubscriptionSet
, since (a) the team saw little actual use-case for it, (b) it would bloat our SDK code, and (c) there is a simple workaround if needed (spreading into an array [...realm.subscriptions]
). (The property length
is available.) Again, something we would love feedback on.ObjectPropsType
, UserMap
, UserType
, BaseFunctionsFactory
, AuthProviders
, PropertyType
, HTTP
, *Details
interfaces of the EmailPasswordAuthClient
and AuthError
types, since they weren't used internally and not expected to be used by users. Moreover, most of these are very simple to type out for any user relying on it. Similarly, the DictionaryBase
type was introduced to help work around an issue (declaring string index accessors on a class with methods) in our declarations. We consider it an internal detail that got introduced as part of our public API by accident; thus, we ask users to use the Dictionary
type directly. We also decided to rename the Session
class to SyncSession
since it’s now exported directly on the package namespace. Session
will still be available (but deprecated) as Realm.Sync.Session
. We’re no longer using the *Payload
types (they were only used by Realm Web) and we don’t expect end-users to be relying directly on these, hence they were deleted."list"
instead of "array"
.undefined
or some other default value when calling methods or accessing properties on the JS SyncSession
object, even if that would violate our declared TS types. Now, in v12, we will throw from all methods and property accessors in this case.SubscriptionsState
enum (will be removed in v13) in favor of the now-named SubscriptionSetState
. (#5773)Realm.setLogger
, that allows to setup a single static logger for the duration of the app lifetime. Differently from the now deprecated sync logger (that was setup with Sync.setLogger
), this new one will emit messages coming also from the local database, and not only from sync. It is also possible to change the log level during the whole duration of the app lifetime with Realm.setLogLevel
. (#2546)CompensatingWriteError
which indicates that one or more object changes have been reverted by the server.
This can happen when the client creates/updates objects that do not match any subscription, or performs writes on an object it didn't have permission to access. (#5599)Results
instance via Results.subscribe()
(asynchronous) and Results.unsubscribe()
(synchronous). (#5772)
WaitForSync
enum specifying whether to wait or not wait for subscribed objects to be downloaded before resolving the promise returned from Results.subscribe()
.SubscriptionOptions
to take a WaitForSync
behavior and a maximum waiting timeout before returning from Results.subscribe()
.MutableSubscriptionSet.removeUnnamed()
for removing only unnamed subscriptions.const peopleOver20 = await realm
.objects("Person")
.filtered("age > 20")
.subscribe({
name: "peopleOver20",
behavior: WaitForSync.FirstTime, // Default
timeout: 2000,
});
// ...
peopleOver20.unsubscribe();
CanonicalGeoPoint
can be queried. (#5850)
geoWithin
operator in the query string to Results.filtered()
.GeoCircle
type, defined by its center and radius in radians), box (GeoBox
type, defined by its bottom left and upper right corners) and polygon (GeoPolygon
type, defined by its vertices).kmToRadians()
and miToRadians()
, that can be used to convert kilometers and miles to radians respectively, simplifying conversion of a circle's radius.import Realm, {
ObjectSchema,
GeoCircle,
CanonicalGeoPoint,
GeoPosition,
kmToRadians,
} from "realm";
// Example of a user-defined point class that can be queried using geospatial queries
class MyGeoPoint extends Realm.Object implements CanonicalGeoPoint {
coordinates!: GeoPosition;
type = "Point" as const;
static schema: ObjectSchema = {
name: "MyGeoPoint",
embedded: true,
properties: {
type: "string",
coordinates: "double[]",
},
};
}
class PointOfInterest extends Realm.Object {
name!: string;
location!: MyGeoPoint;
static schema: ObjectSchema = {
name: "PointOfInterest",
properties: {
name: "string",
location: "MyGeoPoint",
},
};
}
realm.write(() => {
realm.create(PointOfInterest, {
name: "Copenhagen",
location: {
coordinates: [12.558892784045568, 55.66717839648401],
type: "Point",
} as MyGeoPoint
});
realm.create(PointOfInterest, {
name: "New York",
location: {
coordinates: [-73.92474936213434, 40.700090994927415],
type: "Point",
} as MyGeoPoint
});
});
const pois = realm.objects(PointOfInterest);
const berlinCoordinates: GeoPoint = [13.397255909303222, 52.51174463251085];
const radius = kmToRadians(500); //500 km = 0.0783932519 rad
// Circle with a radius of 500kms centered in Berlin
const circleShape: GeoCircle = {
center: berlinCoordinates,
distance: radius,
};
// All points of interest in a 500kms radius from Berlin
let result = pois.filtered("location geoWithin $0", circleShape);
// Equivalent string query without arguments
result = pois.filtered("location geoWithin geoCircle([13.397255909303222, 52.51174463251085], 0.0783932519)");
SchemaParseError
(or one of its subtypes ObjectSchemaParseError
and PropertySchemaParseError
) rather than an AssertionError
or Error
. (#5198)SSLConfiguration
with a custom function for validating the server's SSL certificate. (#5485)PropertySchema.indexed
with the full-text
option, that allows to create an index for full-text search queries. (#5755)TRUEPREDICATE SORT(meta['age'])
. (realm/realm-core#5311)SyncError.logUrl
which contains the URL to the server log related to the sync error. (#5609)Realm.Results#length
) the number of exact matches (with no other query conditions) on a string
/int
/uuid
/objectId
property that has an index. This improvement will be especially noticeable if there are a large number of results returned (duplicate values).date
property that has an index.mixed
property that has an index.bool
property that has an index.mixed
property that does not have an index.THROW_ON_GLOBAL_REALM
which will enable throwing when the app is accessing the Realm
without first importing it from the Realm package.yarn
and the bson
dependency. (#6040)realm
binary is missing and provide guidance in the README.md
. (#5981)UpdateMode
recursively to all objects when passed to Realm.create()
. (#5933)Realm
was still open (realm/realm-core#6050).User.state
and changed the UserState
enum values to use pascal case to conform to the v11 implementation (except for UserState.Active
that we now deprecate in favor of UserState.LoggedIn
). (#5686)App.currentUser()
when being called on a new instance of App
(#5790)mixed
property with a string operator (contains
/like
/beginswith
/endswith
) or with case insensitivity. ([realm/realm-core#6376](https://github.com/realm/realm-core/issues/6376, since v10.5.0)mixed
property was returning case insensitive matches. For example querying for myIndexedMixed == "Foo"
would incorrectly match on values of "foo"
or "FOO"
. (realm/realm-core#6376, since v10.5.0)mixed
property on a non-empty class/objectType would crash with an assertion. (realm/realm-core#6376, since v10.5.0)Realm.App.Sync#pause()
could hold a reference to the database open after shutting down the sync session, preventing users from being able to delete the Realm. (realm/realm-core#6372, since v11.5.0)Realm.Results
and Realm.List
being in different orders on different devices. Moreover, some cases of the error message Invalid prior_size
may have be fixed too. (realm/realm-core#6191, since v10.15.0)Sync
as named export. #5649App.allUsers
to return a record with the User.id
as the key and the User
as the value. #5671@keys
in a Dictionary would throw an exception. (realm/realm-core#6831, since v12.0.0-rc.3)REALM_DISABLE_ANALYTICS
, and you can print out what is submitted by setting the environment variable REALM_PRINT_ANALYTICS
.Changelog
12.0.0-rc.3 (2023-08-03)
Using Realm Core from v13.15.1 to v13.17.1
Changelog
12.0.0-rc.2 (2023-07-14)
ClassMap
) used by Realm
before notifying schema change listeners when the schema is changed during runtime. (#5574)UpdateMode
recursively to all objects when passed to Realm.create()
. (#5933)fs-extra
), and the post-install script has been refactored to use fs
instead.Changelog
12.0.0-rc.1 (2023-06-30)
Changelog
12.0.0-rc.0 (2023-06-29)
Realm
to use default or * as Realm
imports of the Realm
constructor. (#5882)SyncSession
JS objects no longer keep their associated C++ objects, and therefore the sync network connection, alive. This was causing issues because JS garbage collection is lazy so the SyncSession
may survive much longer than the last reference held to it. We now use the same technique as v11 to avoid keeping the C++ object alive (std::weak_ptr
). (#5815, since v12.0.0-alpha.0)
undefined
or some other default value when calling methods or accessing properties on the JS SyncSession
object, even if that would violate our declared TS types. Now, in v12, we will throw from all methods and property accessors in this case.SubscriptionsState
enum (will be removed in v13) in favor of the now-named SubscriptionSetState
. (#5773)Realm
namespace, to align with v11 and ease the adoption of this major version. (#5883)Opening a Realm with invalid schemas will throw a SchemaParseError
(or one of its subtypes ObjectSchemaParseError
and PropertySchemaParseError
) rather than an AssertionError
or Error
. (#5198)
Enable multiple processes to operate on an encrypted Realm simultaneously. (realm/realm-core#1845)
Added Realm.setLogger
, that allows to setup a single static logger for the duration of the app lifetime. Differently from the now deprecated sync logger (that was setup with Sync.setLogger
), this new one will emit messages coming also from the local database, and not only from sync. It is also possible to change the log level during the whole duration of the app lifetime with Realm.setLogLevel
. (#2546)
Added support for a sync configuration option to provide an SSLConfiguration
with a custom function for validating the server's SSL certificate. (#5485)
Improve performance of equality queries on a non-indexed mixed property by about 30%. (realm/realm-core#6506)
Improve performance of rolling back write transactions after making changes. (realm/realm-core#6513)
Extended PropertySchema.indexed
with the full-text
option, that allows to create an index for full-text search queries. (#5755)
Access token refresh for websockets was not updating the location metadata. (realm/realm-core#6630, since v11.9.0)
Fix several UBSan failures which did not appear to result in functional bugs. (realm/realm-core#6649).
Using both synchronous and asynchronous transactions on the same thread or scheduler could hit an assertion failure if one of the callbacks for an asynchronous transaction happened to be scheduled during a synchronous transaction (realm/realm-core#6659, since v10.12.0)
Added APIs to facilitate adding and removing subscriptions. (#5772)
Results
instance via Results.subscribe()
(asynchronous) and Results.unsubscribe()
(synchronous).
WaitForSync
enum specifying whether to wait or not wait for subscribed objects to be downloaded before resolving the promise returned from Results.subscribe()
.SubscriptionOptions
to take a WaitForSync
behavior and a maximum waiting timeout before returning from Results.subscribe()
.MutableSubscriptionSet.removeUnnamed()
for removing only unnamed subscriptions.const peopleOver20 = await realm
.objects("Person")
.filtered("age > 20")
.subscribe({
name: "peopleOver20",
behavior: WaitForSync.FirstTime, // Default
timeout: 2000,
});
// ...
peopleOver20.unsubscribe();
Added initial support for geospatial queries, with the possibility of querying points. No new data type has been added in this phase, but every embedded object property that conforms to CanonicalGeoPoint
can be queried. (#5850)
geoWithin
operator in the query string to Results.filtered()
.GeoCircle
type, defined by its center and radius in radians), box (GeoBox
type, defined by its bottom left and upper right corners) and polygon (GeoPolygon
type, defined by its vertices).kmToRadians()
and miToRadians()
, that can be used to convert kilometers and miles to radians respectively, simplifying conversion of a circle's radius.import Realm, {
ObjectSchema,
GeoCircle,
CanonicalGeoPoint,
GeoPosition,
kmToRadians,
} from "realm";
// Example of a user-defined point class that can be queried using geospatial queries
class MyGeoPoint extends Realm.Object implements CanonicalGeoPoint {
coordinates!: GeoPosition;
type = "Point" as const;
static schema: ObjectSchema = {
name: "MyGeoPoint",
embedded: true,
properties: {
type: "string",
coordinates: "double[]",
},
};
}
class PointOfInterest extends Realm.Object {
name!: string;
location!: MyGeoPoint;
static schema: ObjectSchema = {
name: "PointOfInterest",
properties: {
name: "string",
location: "MyGeoPoint",
},
};
}
realm.write(() => {
realm.create(PointOfInterest, {
name: "Copenhagen",
location: {
coordinates: [12.558892784045568, 55.66717839648401],
type: "Point",
} as MyGeoPoint
});
realm.create(PointOfInterest, {
name: "New York",
location: {
coordinates: [-73.92474936213434, 40.700090994927415],
type: "Point",
} as MyGeoPoint
});
});
const pois = realm.objects(PointOfInterest);
const berlinCoordinates: GeoPoint = [13.397255909303222, 52.51174463251085];
const radius = kmToRadians(500); //500 km = 0.0783932519 rad
// Circle with a radius of 500kms centered in Berlin
const circleShape: GeoCircle = {
center: berlinCoordinates,
distance: radius,
};
// All points of interest in a 500kms radius from Berlin
let result = pois.filtered("location geoWithin $0", circleShape);
// Equivalent string query without arguments
result = pois.filtered("location geoWithin geoCircle([13.397255909303222, 52.51174463251085], 0.0783932519)");
Support sort/distinct based on values from a dictionary e.g. TRUEPREDICATE SORT(meta['age'])
. (realm/realm-core#5311)
Support for HTTP proxy settings in the Realm configuration by adding proxyConfig
to the sync configuration. You can continue to use environment variable HTTPS_PROXY
. HTTP proxies are only supported for node.js and Electron. (#5816)
proxyConfig: {
address: "127.0.0.1",
port: 9876,
type: ProxyType.HTTP,
}
Realm
was still open (realm/realm-core#6050).User.state
and changed the UserState
enum values to use pascal case to conform to the v11 implementation (except for UserState.Active
that we now deprecate in favor of UserState.LoggedIn
). (#5686)indexOf
a missing value will no longer return 4294967295
instead of -1
and the Set#has
will no longer return true
when missing. Caused by an incorrect conversion of size_t
to Number
on x86 (32bit) architectures. (#5746, since 12.0.0-alpha.0)App.currentUser()
when being called on a new instance of App
(#5790)REALM_DISABLE_ANALYTICS
, and you can print out what is submitted by setting the environment variable REALM_PRINT_ANALYTICS
.