From 528c3d714042f7b829610b864d422671f672c621 Mon Sep 17 00:00:00 2001 From: Kenneth Geisshirt Date: Tue, 23 Jul 2024 10:17:00 +0200 Subject: [PATCH] RJS-2841: Upgrade to Realm Core v14.11.0 (#6739) --- CHANGELOG.md | 19 ++++++++- integration-tests/tests/src/tests/results.ts | 40 ++++++++++++++++++- integration-tests/tests/src/tests/sync/app.ts | 38 ++++++++++++------ packages/realm/bindgen/vendor/realm-core | 2 +- 4 files changed, 83 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 585e7f3c81..9808b84477 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,10 +13,24 @@ realm.syncSession?.addProgressNotification( (estimate) => console.log(`progress: ${estimate}/1.0`) ); ``` +* It is no longer an error to set a base url for an App with a trailing slash - for example, `https://services.cloud.mongodb.com/` instead of `https://services.cloud.mongodb.com` - before this change that would result in a 404 error from the server. ([realm/realm-core#7791](https://github.com/realm/realm-core/pull/7791)) +* Performance has been improved for range queries on integers and timestamps when using the `BETWEEN` operator. ([realm/realm-core#7785](https://github.com/realm/realm-core/pull/7785)) +* On Windows devices Device Sync will additionally look up SSL certificates in the Windows Trusted Root Certification Authorities certificate store when establishing a connection. ([realm/realm-core#7882](https://github.com/realm/realm-core/pull/7882)) +* Role and permissions changes no longer require a client reset to update the Realm on-device. ([realm/realm-core#7440](https://github.com/realm/realm-core/pull/7440)) ### Fixed -* ([#????](https://github.com/realm/realm-js/issues/????), since v?.?.?) -* None +* Opening an Flexible Sync Realm asynchronously may not wait to download all data. ([realm/realm-core#7720](https://github.com/realm/realm-core/issues/7720), since v10.12.0) +* Clearing a list of `mixed` in an upgraded file would lead to an assertion failing. ([realm/realm-core#7771](https://github.com/realm/realm-core/issues/7771), since 12.7.0-rc.0) +* Sync client can crash if a session is resumed while the session is being suspended. ([realm/realm-core#7860](https://github.com/realm/realm-core/issues/7860), since v10.18.0) +* If a sync session is interrupted by a disconnect or restart while downloading a bootstrap, stale data from the previous bootstrap may be included when the session reconnects and downloads the bootstrap. This can lead to objects stored in the database that do not match the actual state of the server and potentially leading to compensating writes. ([realm/realm-core#7827](https://github.com/realm/realm-core/issues/7827), since v10.18.0) +* Fixed unnecessary server roundtrips when there is no download to acknowledge. ([realm/realm-core#2129](https://jira.mongodb.org/browse/RCORE-2129), since v12.10.0) +* `Realm.App.Sync.SyncSession#uploadAllLocalChanges()` was inconsistent in how it handled commits which did not produce any changesets to upload. Previously it would sometimes complete immediately if all commits waiting to be uploaded were empty, and at other times it would wait for a server roundtrip. It will now always complete immediately. ([realm/realm-core#7796](https://github.com/realm/realm-core/pull/7796)) +* `Realm#writeCopyTo()` on an encrypted Realm without explicitly specifying a new encryption key would only work if the old key happened to be a valid nul-terminated string. ([realm/realm-core#7842](https://github.com/realm/realm-core/issues/7842), since v12.10.0). +* You could get unexpected merge results when assigning to a nested collection. ([realm/realm-core#7809](https://github.com/realm/realm-core/issues/7809), since v12.7.0-rc.0) +* When `mapTo` is used to have an alias for a property name, `Realm.Results#sorted()` doesn't recognize the alias leading to errors like `Cannot sort on key path 'NAME': property 'PersonObject.NAME' does not exist`. ([#6779](https://github.com/realm/realm-js/issues/6779), since v11.2.0) +* A `mixed` property with a collection could sometimes end up with a combination of values assigned by different clients. ([realm/realm-core#7809](https://github.com/realm/realm-core/issues/7809), since v12.9.0) +* Fixed removing backlinks from the wrong objects if the link came from a nested list, nested dictionary, top-level dictionary, or list of mixed, and the source table had more than 256 objects. This could manifest as `array_backlink.cpp:112: Assertion failed: int64_t(value >> 1) == key.value` when removing an object. ([realm/realm-core#7594](https://github.com/realm/realm-core/issues/7594), since v10.6.0) +* Fixed a bug when removing an object from a nested collection could lead to an assert with the message `array.cpp:319: Array::move() Assertion failed: begin <= end [2, 1]`. ([realm/realm-core#7839](https://github.com/realm/realm-core/issues/7839), since v12.9.0) ### Compatibility * React Native >= v0.71.4 @@ -26,6 +40,7 @@ realm.syncSession?.addProgressNotification( ### Internal * Adding a CallInvoker-based scheduler for Core on React Native and removing the "flush ui queue" workaround. ([#6791](https://github.com/realm/realm-js/pull/6791)) * Refactors throwing uncaught exceptions from callbacks dispatched onto the event loop from C++ on React Native. ([#6772](https://github.com/realm/realm-js/issues/6772)) +* Upgraded Realm Core from v14.10.0 to v14.11.0. ([#6744](https://github.com/realm/realm-js/issues/6744) ## 12.11.1 (2024-06-25) diff --git a/integration-tests/tests/src/tests/results.ts b/integration-tests/tests/src/tests/results.ts index 1ca46597ea..6f6d5db3ce 100644 --- a/integration-tests/tests/src/tests/results.ts +++ b/integration-tests/tests/src/tests/results.ts @@ -402,7 +402,7 @@ describe("Results", () => { static schema: Realm.ObjectSchema = { name: "PersonObject", properties: { - name: "string", + name: { type: "string", mapTo: "NAME" }, age: "double", married: { type: "bool", default: false }, children: { type: "list", objectType: "PersonObject" }, @@ -535,6 +535,44 @@ describe("Results", () => { realm.close(); }); + it("sorted mapped a property", () => { + const realm = new Realm({ schema: [PersonObject] }); + realm.write(function () { + realm.create("PersonObject", { name: "Ari", age: 10 }); + realm.create("PersonObject", { name: "Tim", age: 11 }); + realm.create("PersonObject", { name: "Bjarne", age: 12 }); + realm.create("PersonObject", { name: "Alex", age: 12, married: true }); + }); + + for (const propname of ["name", "NAME"]) { + const persons = realm.objects("PersonObject").sorted(propname); + expect(persons.length).equals(4); + expect(persons[0].name).equals("Alex"); + expect(persons[0].age).equals(12); + } + + realm.close(); + }); + + it("sorted mapped a property in RQL", () => { + const realm = new Realm({ schema: [PersonObject] }); + realm.write(function () { + realm.create("PersonObject", { name: "Ari", age: 10 }); + realm.create("PersonObject", { name: "Tim", age: 11 }); + realm.create("PersonObject", { name: "Bjarne", age: 12 }); + realm.create("PersonObject", { name: "Alex", age: 12, married: true }); + }); + + for (const propname of ["name", "NAME"]) { + const persons = realm.objects("PersonObject").filtered(`age > 0 SORT(${propname} ASC)`); + expect(persons.length).equals(4); + expect(persons[0].name).equals("Alex"); + expect(persons[0].age).equals(12); + } + + realm.close(); + }); + it("implements sorted correctly with all types", () => { const realm = new Realm({ schema: [BasicTypesSchema] }); let objects = realm.objects("BasicTypesObject"); diff --git a/integration-tests/tests/src/tests/sync/app.ts b/integration-tests/tests/src/tests/sync/app.ts index 47c8527586..2d5d0b54b5 100644 --- a/integration-tests/tests/src/tests/sync/app.ts +++ b/integration-tests/tests/src/tests/sync/app.ts @@ -75,7 +75,9 @@ interface IDogForSyncSchema { realm_id: string | undefined; } -const missingAppConfig = { id: "smurf", baseUrl }; +function missingAppConfig(): Realm.AppConfiguration { + return { id: new BSON.UUID().toString(), baseUrl }; +} describe("App", () => { describe("instantiation", function () { @@ -85,15 +87,16 @@ describe("App", () => { it("from config", () => { //even if "id" is not an existing app we can still instantiate a new Realm. - const app = new Realm.App(missingAppConfig); + const app = new Realm.App(missingAppConfig()); expect(app).instanceOf(Realm.App); }); it("from string", () => { //even if "id" is not an existing app we can still instantiate a new Realm. - const app = new Realm.App(missingAppConfig.id); + const id = missingAppConfig().id; + const app = new Realm.App(id); expect(app).instanceOf(Realm.App); - expect(app.id).equals(missingAppConfig.id); + expect(app.id).equals(id); }); it("throws on undefined app", function () { @@ -115,21 +118,23 @@ describe("App", () => { }); it("logging in throws on invalid baseURL", async function () { - const invalidUrlConf = { id: missingAppConfig.id, baseUrl: "http://localhost:9999" }; + const id = missingAppConfig().id; + const invalidUrlConf = { id, baseUrl: "http://localhost:9999" }; const app = new Realm.App(invalidUrlConf); const credentials = Realm.Credentials.anonymous(); await expect(app.logIn(credentials)).to.be.rejectedWith( select({ reactNative: "Network request failed", - default: "request to http://localhost:9999/api/client/v2.0/app/smurf/location failed", + default: `request to http://localhost:9999/api/client/v2.0/app/${id}/location failed`, }), ); }); it("get returns cached app", () => { - const app = Realm.App.get(missingAppConfig.id); - const cachedApp = Realm.App.get(missingAppConfig.id); + const appConfig = missingAppConfig(); + const app = Realm.App.get(appConfig.id); + const cachedApp = Realm.App.get(appConfig.id); expect(app).instanceOf(Realm.App); expect(app).equals(cachedApp); @@ -137,7 +142,7 @@ describe("App", () => { }); describe("how to handle metadata", () => { - afterEach(async () => { + afterEach(() => { Realm.clearTestState(); }); @@ -158,7 +163,15 @@ describe("App", () => { it("persists and encrypts a user", () => { const encryptionKey = new ArrayBuffer(64); - const config: AppConfiguration = { id: "smurf", metadata: { mode: MetadataMode.Encryption, encryptionKey } }; + // as metadata is cached within the same process, we need to use another app id + // see also https://github.com/realm/realm-core/issues/7876 + const config: AppConfiguration = { + id: "cryptosmurf", + metadata: { + mode: MetadataMode.Encryption, + encryptionKey, + }, + }; const app = new Realm.App(config); expect(app).instanceOf(Realm.App); }); @@ -180,9 +193,10 @@ describe("App", () => { it("logging in throws on non existing app", async function () { // This test is moved here to ensure the server is available before connecting with a non-exisiting app id - const app = new Realm.App(missingAppConfig); + const appConfig = missingAppConfig(); + const app = new Realm.App(appConfig); const credentials = Realm.Credentials.anonymous(); - await expect(app.logIn(credentials)).to.be.rejectedWith("cannot find app using Client App ID 'smurf'"); + await expect(app.logIn(credentials)).to.be.rejectedWith(`cannot find app using Client App ID '${appConfig.id}'`); }); it("logins successfully ", async function (this: Mocha.Context & AppContext & RealmContext) { diff --git a/packages/realm/bindgen/vendor/realm-core b/packages/realm/bindgen/vendor/realm-core index 6bebc40a03..60867846a0 160000 --- a/packages/realm/bindgen/vendor/realm-core +++ b/packages/realm/bindgen/vendor/realm-core @@ -1 +1 @@ -Subproject commit 6bebc40a03ca4144050bc672a6cd86c2286caa32 +Subproject commit 60867846a0aca0c7da5e482282b293236f730216