From 9364039e5ad1a235c8c4888c95f8ea17413bd294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kr=C3=A6n=20Hansen?= Date: Wed, 7 Aug 2024 12:46:32 +0200 Subject: [PATCH] Avoid circular imports (#6814) --- package-lock.json | 799 ++++++++++++++++-- package.json | 5 +- packages/realm-react/src/UserProvider.tsx | 16 +- packages/realm-react/tsconfig.json | 2 +- packages/realm/.eslintrc.json | 1 + packages/realm/.madgerc | 11 + packages/realm/package.json | 13 +- packages/realm/src/ClassHelpers.ts | 18 +- packages/realm/src/ClassMap.ts | 29 +- packages/realm/src/Collection.ts | 27 +- packages/realm/src/Configuration.ts | 20 +- packages/realm/src/Counter.ts | 8 +- packages/realm/src/Dictionary.ts | 160 +--- packages/realm/src/GeoSpatial.ts | 2 +- packages/realm/src/JSONCacheMap.ts | 8 +- packages/realm/src/List.ts | 157 +--- packages/realm/src/Logger.ts | 4 +- packages/realm/src/Object.ts | 92 +- packages/realm/src/ObjectListeners.ts | 9 +- packages/realm/src/OrderedCollection.ts | 104 +-- packages/realm/src/ProgressRealmPromise.ts | 38 +- packages/realm/src/PromiseHandle.ts | 5 +- packages/realm/src/PropertyHelpers.ts | 5 +- packages/realm/src/PropertyMap.ts | 7 +- packages/realm/src/Realm.ts | 434 +++++----- packages/realm/src/RealmListeners.ts | 3 +- packages/realm/src/Results.ts | 85 +- packages/realm/src/Set.ts | 103 +-- packages/realm/src/TypeHelpers.ts | 7 +- packages/realm/src/Types.ts | 25 +- packages/realm/src/Unmanaged.ts | 17 +- packages/realm/src/app-services/ApiKeyAuth.ts | 4 +- packages/realm/src/app-services/App.ts | 37 +- packages/realm/src/app-services/Auth.ts | 9 +- .../src/app-services/BaseSubscriptionSet.ts | 23 +- .../realm/src/app-services/Credentials.ts | 4 +- .../src/app-services/EmailPasswordAuth.ts | 2 +- .../src/app-services/FunctionsFactory.ts | 2 +- packages/realm/src/app-services/MongoDB.ts | 62 +- .../src/app-services/MongoDBCollection.ts | 7 +- .../app-services/MutableSubscriptionSet.ts | 22 +- .../src/app-services/NetworkTransport.ts | 5 +- packages/realm/src/app-services/PushClient.ts | 2 +- packages/realm/src/app-services/Services.ts | 10 +- .../realm/src/app-services/Subscription.ts | 4 +- .../realm/src/app-services/SubscriptionSet.ts | 15 +- packages/realm/src/app-services/Sync.ts | 60 +- .../src/app-services/SyncConfiguration.ts | 32 +- .../realm/src/app-services/SyncSession.ts | 45 +- packages/realm/src/app-services/User.ts | 52 +- packages/realm/src/app-services/utils.ts | 2 +- packages/realm/src/assert.ts | 16 +- .../realm/src/async-iterator-from-response.ts | 2 +- .../src/collection-accessors/Dictionary.ts | 143 ++++ .../realm/src/collection-accessors/List.ts | 152 ++++ .../collection-accessors/OrderedCollection.ts | 53 ++ .../realm/src/collection-accessors/Results.ts | 74 ++ .../realm/src/collection-accessors/Set.ts | 102 +++ packages/realm/src/deprecated-global.ts | 298 +++---- packages/realm/src/errors.ts | 8 +- packages/realm/src/index.ts | 2 + packages/realm/src/indirect.ts | 76 ++ .../realm/src/{internal.ts => namespace.ts} | 43 - packages/realm/src/platform/binding-patch.ts | 3 +- .../realm/src/platform/node/custom-inspect.ts | 11 +- packages/realm/src/platform/node/index.ts | 4 +- .../realm/src/platform/react-native/index.ts | 2 + .../realm/src/property-accessors/Array.ts | 19 +- .../src/property-accessors/Dictionary.ts | 15 +- packages/realm/src/property-accessors/Int.ts | 2 +- .../realm/src/property-accessors/Mixed.ts | 14 +- .../realm/src/property-accessors/Object.ts | 3 +- packages/realm/src/property-accessors/Set.ts | 8 +- .../realm/src/property-accessors/default.ts | 5 +- .../realm/src/property-accessors/types.ts | 8 +- packages/realm/src/schema/from-binding.ts | 5 +- packages/realm/src/schema/normalize.ts | 12 +- packages/realm/src/schema/to-binding.ts | 4 +- packages/realm/src/schema/types.ts | 4 +- packages/realm/src/schema/validate.ts | 15 +- packages/realm/src/scripts/build/android.ts | 2 +- packages/realm/src/scripts/build/apple.ts | 3 +- packages/realm/src/symbols.ts | 21 + .../src/tests/collection-helpers.test.ts | 2 +- packages/realm/src/tests/list.test.ts | 3 +- packages/realm/src/tests/milestone-2.test.ts | 9 +- packages/realm/src/tests/milestone-3.test.ts | 7 +- packages/realm/src/tests/milestone-4.test.ts | 7 +- packages/realm/src/tests/milestone-5.test.ts | 8 +- packages/realm/src/tests/platform.test.ts | 2 +- .../src/tests/schema-normalization.test.ts | 2 +- .../realm/src/tests/schema-transform.test.ts | 2 +- packages/realm/src/tests/schema-utils.test.ts | 2 +- packages/realm/src/tests/updateschema.test.ts | 5 +- packages/realm/src/type-helpers/Array.ts | 8 +- packages/realm/src/type-helpers/Bool.ts | 2 +- packages/realm/src/type-helpers/Data.ts | 2 +- packages/realm/src/type-helpers/Date.ts | 5 +- packages/realm/src/type-helpers/Decimal.ts | 5 +- packages/realm/src/type-helpers/Double.ts | 4 +- packages/realm/src/type-helpers/Float.ts | 5 +- packages/realm/src/type-helpers/Int.ts | 4 +- .../realm/src/type-helpers/LinkingObjects.ts | 5 +- packages/realm/src/type-helpers/Mixed.ts | 44 +- packages/realm/src/type-helpers/Object.ts | 13 +- packages/realm/src/type-helpers/ObjectId.ts | 5 +- packages/realm/src/type-helpers/String.ts | 4 +- packages/realm/src/type-helpers/Uuid.ts | 5 +- .../realm/src/type-helpers/array-buffer.ts | 4 +- packages/realm/src/type-helpers/default.ts | 2 +- packages/realm/src/type-helpers/types.ts | 6 +- 111 files changed, 2419 insertions(+), 1495 deletions(-) create mode 100644 packages/realm/.madgerc create mode 100644 packages/realm/src/collection-accessors/Dictionary.ts create mode 100644 packages/realm/src/collection-accessors/List.ts create mode 100644 packages/realm/src/collection-accessors/OrderedCollection.ts create mode 100644 packages/realm/src/collection-accessors/Results.ts create mode 100644 packages/realm/src/collection-accessors/Set.ts create mode 100644 packages/realm/src/indirect.ts rename packages/realm/src/{internal.ts => namespace.ts} (66%) create mode 100644 packages/realm/src/symbols.ts diff --git a/package-lock.json b/package-lock.json index be448c3ac9..0698b64e6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,6 +59,9 @@ "typescript": "5.0.4", "wireit": "^0.14.4" }, + "devDependencies": { + "madge": "^7.0.0" + }, "engines": { "node": ">=20", "npm": ">=10" @@ -2848,7 +2851,6 @@ "version": "10.5.0", "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-10.5.0.tgz", "integrity": "sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==", - "dev": true, "dependencies": { "@chevrotain/gast": "10.5.0", "@chevrotain/types": "10.5.0", @@ -2859,7 +2861,6 @@ "version": "10.5.0", "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-10.5.0.tgz", "integrity": "sha512-pXdMJ9XeDAbgOWKuD1Fldz4ieCs6+nLNmyVhe2gZVqoO7v8HXuHYs5OV2EzUtbuai37TlOAQHrTDvxMnvMJz3A==", - "dev": true, "dependencies": { "@chevrotain/types": "10.5.0", "lodash": "4.17.21" @@ -2868,20 +2869,17 @@ "node_modules/@chevrotain/types": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-10.5.0.tgz", - "integrity": "sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A==", - "dev": true + "integrity": "sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A==" }, "node_modules/@chevrotain/utils": { "version": "10.5.0", "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-10.5.0.tgz", - "integrity": "sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==", - "dev": true + "integrity": "sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==" }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -2893,12 +2891,25 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@dependents/detective-less": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@dependents/detective-less/-/detective-less-4.1.0.tgz", + "integrity": "sha512-KrkT6qO5NxqNfy68sBl6CTSoJ4SNDIS5iQArkibhlbGU4LaDukZ3q2HIkh8aUKDio6o4itU4xDR7t82Y2eP1Bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^6.0.1" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/@develar/schema-utils": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", @@ -5898,26 +5909,22 @@ "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" }, "node_modules/@tsconfig/node18": { "version": "18.2.2", @@ -7233,6 +7240,13 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -7454,6 +7468,13 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/appdirsjs": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/appdirsjs/-/appdirsjs-1.2.7.tgz", @@ -7540,8 +7561,7 @@ "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" }, "node_modules/argparse": { "version": "2.0.1", @@ -7740,6 +7760,16 @@ "node": "*" } }, + "node_modules/ast-module-types": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-5.0.0.tgz", + "integrity": "sha512-JvqziE0Wc0rXQfma0HZC/aY7URXHFuZV84fJRtP8u+lhp0JYCNd5wJzVXP45t0PH0Mej3ynlzvdyITYIu0G4LQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/ast-types": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.15.2.tgz", @@ -8959,7 +8989,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, "dependencies": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" @@ -8996,7 +9025,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", - "dev": true, "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", @@ -9079,7 +9107,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", - "dev": true, "dependencies": { "camel-case": "^4.1.2", "capital-case": "^1.0.4", @@ -9128,7 +9155,6 @@ "version": "10.5.0", "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-10.5.0.tgz", "integrity": "sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==", - "dev": true, "dependencies": { "@chevrotain/cst-dts-gen": "10.5.0", "@chevrotain/gast": "10.5.0", @@ -10028,7 +10054,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", - "dev": true, "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", @@ -10233,8 +10258,7 @@ "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" }, "node_modules/cross-env": { "version": "7.0.3", @@ -10664,6 +10688,25 @@ "node": ">= 0.8" } }, + "node_modules/dependency-tree": { + "version": "10.0.9", + "resolved": "https://registry.npmjs.org/dependency-tree/-/dependency-tree-10.0.9.tgz", + "integrity": "sha512-dwc59FRIsht+HfnTVM0BCjJaEWxdq2YAvEDy4/Hn6CwS3CBWMtFnL3aZGAkQn3XCYxk/YcTDE4jX2Q7bFTwCjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^10.0.1", + "filing-cabinet": "^4.1.6", + "precinct": "^11.0.5", + "typescript": "^5.0.4" + }, + "bin": { + "dependency-tree": "bin/cli.js" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/des.js": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", @@ -10709,6 +10752,135 @@ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" }, + "node_modules/detective-amd": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-5.0.2.tgz", + "integrity": "sha512-XFd/VEQ76HSpym80zxM68ieB77unNuoMwopU2TFT/ErUk5n4KvUTwW4beafAVUugrjV48l4BmmR0rh2MglBaiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-module-types": "^5.0.0", + "escodegen": "^2.0.0", + "get-amd-module-type": "^5.0.1", + "node-source-walk": "^6.0.1" + }, + "bin": { + "detective-amd": "bin/cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/detective-cjs": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-5.0.1.tgz", + "integrity": "sha512-6nTvAZtpomyz/2pmEmGX1sXNjaqgMplhQkskq2MLrar0ZAIkHMrDhLXkRiK2mvbu9wSWr0V5/IfiTrZqAQMrmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-module-types": "^5.0.0", + "node-source-walk": "^6.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/detective-es6": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-4.0.1.tgz", + "integrity": "sha512-k3Z5tB4LQ8UVHkuMrFOlvb3GgFWdJ9NqAa2YLUU/jTaWJIm+JJnEh4PsMc+6dfT223Y8ACKOaC0qcj7diIhBKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-source-walk": "^6.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/detective-postcss": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-6.1.3.tgz", + "integrity": "sha512-7BRVvE5pPEvk2ukUWNQ+H2XOq43xENWbH0LcdCE14mwgTBEAMoAx+Fc1rdp76SmyZ4Sp48HlV7VedUnP6GA1Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-url": "^1.2.4", + "postcss": "^8.4.23", + "postcss-values-parser": "^6.0.2" + }, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/detective-sass": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-5.0.3.tgz", + "integrity": "sha512-YsYT2WuA8YIafp2RVF5CEfGhhyIVdPzlwQgxSjK+TUm3JoHP+Tcorbk3SfG0cNZ7D7+cYWa0ZBcvOaR0O8+LlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^6.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/detective-scss": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-4.0.3.tgz", + "integrity": "sha512-VYI6cHcD0fLokwqqPFFtDQhhSnlFWvU614J42eY6G0s8c+MBhi9QAWycLwIOGxlmD8I/XvGSOUV1kIDhJ70ZPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^6.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/detective-stylus": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-4.0.0.tgz", + "integrity": "sha512-TfPotjhszKLgFBzBhTOxNHDsutIxx9GTWjrL5Wh7Qx/ydxKhwUrlSFeLIn+ZaHPF+h0siVBkAQSuy6CADyTxgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/detective-typescript": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-11.2.0.tgz", + "integrity": "sha512-ARFxjzizOhPqs1fYC/2NMC3N4jrQ6HvVflnXBTRqNEqJuXwyKLRr9CrJwkRcV/SnZt1sNXgsF6FPm0x57Tq0rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "^5.62.0", + "ast-module-types": "^5.0.0", + "node-source-walk": "^6.0.2", + "typescript": "^5.4.4" + }, + "engines": { + "node": "^14.14.0 || >=16.0.0" + } + }, + "node_modules/detective-typescript/node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/devtools-protocol": { "version": "0.0.1249869", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz", @@ -10950,7 +11122,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" @@ -12540,6 +12711,33 @@ "node": ">=10" } }, + "node_modules/filing-cabinet": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/filing-cabinet/-/filing-cabinet-4.2.0.tgz", + "integrity": "sha512-YZ21ryzRcyqxpyKggdYSoXx//d3sCJzM3lsYoaeg/FyXdADGJrUl+BW1KIglaVLJN5BBcMtWylkygY8zBp2MrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-module-path": "^2.2.0", + "commander": "^10.0.1", + "enhanced-resolve": "^5.14.1", + "is-relative-path": "^1.0.2", + "module-definition": "^5.0.1", + "module-lookup-amd": "^8.0.5", + "resolve": "^1.22.3", + "resolve-dependency-path": "^3.0.2", + "sass-lookup": "^5.0.1", + "stylus-lookup": "^5.0.1", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.0.4" + }, + "bin": { + "filing-cabinet": "bin/cli.js" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -13056,6 +13254,20 @@ "node": ">=6.9.0" } }, + "node_modules/get-amd-module-type": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-5.0.1.tgz", + "integrity": "sha512-jb65zDeHyDjFR1loOVk0HQGM5WNwoGB8aLWy3LKCieMKol0/ProHkhO2X1JxojuN10vbz1qNn09MJ7tNp7qMzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-module-types": "^5.0.0", + "node-source-walk": "^6.0.1" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -13090,6 +13302,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true, + "license": "ISC" + }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -13376,6 +13595,22 @@ "node": ">=8" } }, + "node_modules/gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "gonzales": "bin/gonzales.js" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -13639,7 +13874,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", - "dev": true, "dependencies": { "capital-case": "^1.0.4", "tslib": "^2.0.3" @@ -14579,6 +14813,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-object": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/is-object/-/is-object-0.1.2.tgz", @@ -14637,6 +14881,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-relative-path": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-relative-path/-/is-relative-path-1.0.2.tgz", + "integrity": "sha512-i1h+y50g+0hRbBD+dbnInl3JlJ702aar58snAeX+MxBAPvzXGej7sYoPMhlnykabt0ZzCJNBEyzMlekuQZN7fA==", + "dev": true, + "license": "MIT" + }, "node_modules/is-set": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", @@ -14726,6 +14987,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-url-superb": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-url-superb/-/is-url-superb-4.0.0.tgz", + "integrity": "sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-weakmap": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", @@ -16553,7 +16834,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, "dependencies": { "tslib": "^2.0.3" } @@ -16584,6 +16864,56 @@ "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==" }, + "node_modules/madge": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/madge/-/madge-7.0.0.tgz", + "integrity": "sha512-x9eHkBWoCJ2B8yGesWf8LRucarkbH5P3lazqgvmxe4xn5U2Meyfu906iG9mBB1RnY/f4D+gtELWdiz1k6+jAZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "commander": "^7.2.0", + "commondir": "^1.0.1", + "debug": "^4.3.4", + "dependency-tree": "^10.0.9", + "ora": "^5.4.1", + "pluralize": "^8.0.0", + "precinct": "^11.0.5", + "pretty-ms": "^7.0.1", + "rc": "^1.2.8", + "stream-to-array": "^2.3.0", + "ts-graphviz": "^1.8.1", + "walkdir": "^0.4.1" + }, + "bin": { + "madge": "bin/cli.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "individual", + "url": "https://www.paypal.me/pahen" + }, + "peerDependencies": { + "typescript": "^3.9.5 || ^4.9.5 || ^5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/madge/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, "node_modules/magic-string": { "version": "0.30.5", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", @@ -16618,8 +16948,7 @@ "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" }, "node_modules/make-fetch-happen": { "version": "13.0.1", @@ -18107,6 +18436,77 @@ "node": ">=10" } }, + "node_modules/module-definition": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-5.0.1.tgz", + "integrity": "sha512-kvw3B4G19IXk+BOXnYq/D/VeO9qfHaapMeuS7w7sNUqmGaA6hywdFHMi+VWeR9wUScXM7XjoryTffCZ5B0/8IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-module-types": "^5.0.0", + "node-source-walk": "^6.0.1" + }, + "bin": { + "module-definition": "bin/cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/module-lookup-amd": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/module-lookup-amd/-/module-lookup-amd-8.0.5.tgz", + "integrity": "sha512-vc3rYLjDo5Frjox8NZpiyLXsNWJ5BWshztc/5KSOMzpg9k5cHH652YsJ7VKKmtM4SvaxuE9RkrYGhiSjH3Ehow==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^10.0.1", + "glob": "^7.2.3", + "requirejs": "^2.3.6", + "requirejs-config-file": "^4.0.0" + }, + "bin": { + "lookup-amd": "bin/cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/module-lookup-amd/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/module-lookup-amd/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/mongodb-realm-cli": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/mongodb-realm-cli/-/mongodb-realm-cli-1.3.4.tgz", @@ -18231,7 +18631,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" @@ -18788,6 +19187,19 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, + "node_modules/node-source-walk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-6.0.2.tgz", + "integrity": "sha512-jn9vOIK/nfqoFCcpK89/VCVaLg1IHE6UVfDOzvqmANaJ/rWCTEdH8RZ1V278nv2jr36BJdyQXIAavBLXpzdlag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.21.8" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/node-stream-zip": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz", @@ -19817,7 +20229,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dev": true, "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -19863,6 +20274,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -19875,7 +20296,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" @@ -19899,7 +20319,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", - "dev": true, "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -19908,8 +20327,7 @@ "node_modules/path-equal": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/path-equal/-/path-equal-1.2.5.tgz", - "integrity": "sha512-i73IctDr3F2W+bsOWDyyVm/lqsXO47aY9nsFZUjTT/aljSbkxHxxCoyZ9UUrM8jK0JVod+An+rl48RCsvWM+9g==", - "dev": true + "integrity": "sha512-i73IctDr3F2W+bsOWDyyVm/lqsXO47aY9nsFZUjTT/aljSbkxHxxCoyZ9UUrM8jK0JVod+An+rl48RCsvWM+9g==" }, "node_modules/path-exists": { "version": "3.0.0", @@ -20019,9 +20437,10 @@ "dev": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -20207,6 +20626,16 @@ "node": ">=10.4.0" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/pod-install": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/pod-install/-/pod-install-0.2.2.tgz", @@ -20216,6 +20645,72 @@ "pod-install": "build/index.js" } }, + "node_modules/postcss": { + "version": "8.4.40", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", + "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-values-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-6.0.2.tgz", + "integrity": "sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "color-name": "^1.1.4", + "is-url-superb": "^4.0.0", + "quote-unquote": "^1.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "postcss": "^8.2.9" + } + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/prebuild": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/prebuild/-/prebuild-13.0.1.tgz", @@ -20711,6 +21206,33 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/precinct": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-11.0.5.tgz", + "integrity": "sha512-oHSWLC8cL/0znFhvln26D14KfCQFFn4KOLSw6hmLhd+LQ2SKt9Ljm89but76Pc7flM9Ty1TnXyrA2u16MfRV3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@dependents/detective-less": "^4.1.0", + "commander": "^10.0.1", + "detective-amd": "^5.0.2", + "detective-cjs": "^5.0.1", + "detective-es6": "^4.0.1", + "detective-postcss": "^6.1.3", + "detective-sass": "^5.0.3", + "detective-scss": "^4.0.3", + "detective-stylus": "^4.0.0", + "detective-typescript": "^11.1.0", + "module-definition": "^5.0.1", + "node-source-walk": "^6.0.2" + }, + "bin": { + "precinct": "bin/cli.js" + }, + "engines": { + "node": "^14.14.0 || >=16.0.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -20783,6 +21305,22 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, + "node_modules/pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-ms": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/proc-log": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", @@ -21189,6 +21727,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/quote-unquote": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quote-unquote/-/quote-unquote-1.0.0.tgz", + "integrity": "sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==", + "dev": true, + "license": "MIT" + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -22304,8 +22849,7 @@ "node_modules/regexp-to-ast": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz", - "integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==", - "dev": true + "integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==" }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", @@ -22491,6 +23035,34 @@ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, + "node_modules/requirejs": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.7.tgz", + "integrity": "sha512-DouTG8T1WanGok6Qjg2SXuCMzszOo0eHeH9hDZ5Y4x8Je+9JB38HdTLT4/VA8OaUhBa0JPVHJ0pyBkM1z+pDsw==", + "dev": true, + "license": "MIT", + "bin": { + "r_js": "bin/r.js", + "r.js": "bin/r.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/requirejs-config-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/requirejs-config-file/-/requirejs-config-file-4.0.0.tgz", + "integrity": "sha512-jnIre8cbWOyvr8a5F2KuqBnY+SDA4NXr/hzEZJG79Mxm2WiFQz2dzhC8ibtPJS7zkmBEl1mxSwp5HhC1W4qpxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esprima": "^4.0.0", + "stringify-object": "^3.2.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -22535,6 +23107,16 @@ "node": ">=8" } }, + "node_modules/resolve-dependency-path": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/resolve-dependency-path/-/resolve-dependency-path-3.0.2.tgz", + "integrity": "sha512-Tz7zfjhLfsvR39ADOSk9us4421J/1ztVBo4rWUkF38hgHK5m0OCZ3NxFVpqHRkjctnwVa15igEUHFJp8MCS7vA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -22919,7 +23501,6 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "dev": true, "engines": { "node": ">=10" } @@ -22938,6 +23519,22 @@ "truncate-utf8-bytes": "^1.0.0" } }, + "node_modules/sass-lookup": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/sass-lookup/-/sass-lookup-5.0.1.tgz", + "integrity": "sha512-t0X5PaizPc2H4+rCwszAqHZRtr4bugo4pgiCvrBFvIX0XFxnr29g77LJcpyj9A0DcKf7gXMLcgvRjsonYI6x4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^10.0.1" + }, + "bin": { + "sass-lookup": "bin/cli.js" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/sax": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", @@ -23079,7 +23676,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", - "dev": true, "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", @@ -23530,7 +24126,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "dev": true, "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -23597,10 +24192,11 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -23875,6 +24471,16 @@ "node": ">= 0.8" } }, + "node_modules/stream-to-array": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", + "integrity": "sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.1.0" + } + }, "node_modules/streamx": { "version": "2.15.6", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.6.tgz", @@ -24005,6 +24611,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -24073,6 +24694,22 @@ "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" }, + "node_modules/stylus-lookup": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/stylus-lookup/-/stylus-lookup-5.0.1.tgz", + "integrity": "sha512-tLtJEd5AGvnVy4f9UHQMw4bkJJtaAcmo54N+ovQBjDY3DuWyK9Eltxzr5+KG0q4ew6v2EHyuWWNnHeiw/Eo7rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^10.0.1" + }, + "bin": { + "stylus-lookup": "bin/cli.js" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/sudo-prompt": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", @@ -24603,6 +25240,20 @@ "write-markdown": "dist/write-markdown.js" } }, + "node_modules/ts-graphviz": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/ts-graphviz/-/ts-graphviz-1.8.2.tgz", + "integrity": "sha512-5YhbFoHmjxa7pgQLkB07MtGnGJ/yhvjmc9uhsnDBEICME6gkPf83SBwLDQqGDoCa3XzUMWLk1AU2Wn1u1naDtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + } + }, "node_modules/ts-jest": { "version": "29.1.2", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.2.tgz", @@ -24754,7 +25405,6 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -24797,7 +25447,6 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -24806,7 +25455,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, "engines": { "node": ">=0.3.1" } @@ -24816,6 +25464,31 @@ "resolved": "https://registry.npmjs.org/ts.cryptojs256/-/ts.cryptojs256-1.0.1.tgz", "integrity": "sha512-9XtEgRVOZBCdpPcCEhfvv9I2AVXdvfI81I/KpFM0wEfbq5JVHlXH7bfIjGQmYrIHGiBEHKsIaStQ87k926J7dA==" }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -25085,7 +25758,6 @@ "version": "0.55.0", "resolved": "https://registry.npmjs.org/typescript-json-schema/-/typescript-json-schema-0.55.0.tgz", "integrity": "sha512-BXaivYecUdiXWWNiUqXgY6A9cMWerwmhtO+lQE7tDZGs7Mf38sORDeQZugfYOZOHPZ9ulsD+w0LWjFDOQoXcwg==", - "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/node": "^16.9.2", @@ -25103,14 +25775,12 @@ "node_modules/typescript-json-schema/node_modules/@types/node": { "version": "16.18.70", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.70.tgz", - "integrity": "sha512-8eIk20G5VVVQNZNouHjLA2b8utE2NvGybLjMaF4lyhA9uhGwnmXF8o+icdXKGSQSNANJewXva/sFUoZLwAaYAg==", - "dev": true + "integrity": "sha512-8eIk20G5VVVQNZNouHjLA2b8utE2NvGybLjMaF4lyhA9uhGwnmXF8o+icdXKGSQSNANJewXva/sFUoZLwAaYAg==" }, "node_modules/typescript-json-schema/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -25130,7 +25800,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -25142,7 +25811,6 @@ "version": "4.8.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -25366,7 +26034,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", - "dev": true, "dependencies": { "tslib": "^2.0.3" } @@ -25375,7 +26042,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", - "dev": true, "dependencies": { "tslib": "^2.0.3" } @@ -25464,8 +26130,7 @@ "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, "node_modules/v8-to-istanbul": { "version": "9.2.0", @@ -25526,6 +26191,16 @@ "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==" }, + "node_modules/walkdir": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", + "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -26486,7 +27161,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, "engines": { "node": ">=6" } @@ -27317,7 +27991,6 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-11.1.0.tgz", "integrity": "sha512-GuvZ38d23H+7Tz2C9DhzCepivsOsky03s5NI+KCy7ke1FNUvsJ2oO47scQ9YaGGhgjgNW5OYYNSADmbjcSoIhw==", - "dev": true, "peerDependencies": { "commander": "11.1.x" } @@ -27326,7 +27999,6 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "dev": true, "engines": { "node": ">=16" } @@ -27334,7 +28006,6 @@ "packages/realm/bindgen/vendor/realm-core": { "name": "@realm/bindgen", "version": "0.1.0", - "dev": true, "dependencies": { "@commander-js/extra-typings": "^11.1.0", "@types/node": "^18.15.10", diff --git a/package.json b/package.json index 85563ff7b7..7cce0e1560 100644 --- a/package.json +++ b/package.json @@ -104,5 +104,8 @@ "typedoc": "^0.25.7", "typescript": "5.0.4", "wireit": "^0.14.4" + }, + "devDependencies": { + "madge": "^7.0.0" } -} \ No newline at end of file +} diff --git a/packages/realm-react/src/UserProvider.tsx b/packages/realm-react/src/UserProvider.tsx index 908fe71f0e..ebb9c8a547 100644 --- a/packages/realm-react/src/UserProvider.tsx +++ b/packages/realm-react/src/UserProvider.tsx @@ -17,14 +17,14 @@ //////////////////////////////////////////////////////////////////////////// import React, { createContext, useContext, useEffect, useReducer, useState } from "react"; -import type Realm from "realm"; +import type { Realm, AnyUser, DefaultFunctionsFactory } from "realm"; import { useApp } from "./AppProvider"; /** * Create a context containing the Realm app. Should be accessed with the useApp hook. */ -export const UserContext = createContext(null); +export const UserContext = createContext(null); type UserProviderProps = { /** @@ -35,7 +35,7 @@ type UserProviderProps = { children: React.ReactNode; }; -function userWasUpdated(userA: Realm.User | null, userB: Realm.User | null) { +function userWasUpdated(userA: AnyUser | null, userB: AnyUser | null) { if (!userA && !userB) { return false; } else if (userA && userB) { @@ -56,7 +56,7 @@ function userWasUpdated(userA: Realm.User | null, userB: Realm.User | null) { */ export const UserProvider: React.FC = ({ fallback: Fallback, children }) => { const app = useApp(); - const [user, setUser] = useState(() => app.currentUser); + const [user, setUser] = useState(() => app.currentUser); const [, forceUpdate] = useReducer((x) => x + 1, 0); // Support for a possible change in configuration. @@ -102,9 +102,9 @@ export const UserProvider: React.FC = ({ fallback: Fallback, * */ export const useUser = < - FunctionsFactoryType extends Realm.DefaultFunctionsFactory, - CustomDataType extends Record, - UserProfileDataType extends Realm.DefaultUserProfileData, + FunctionsFactoryType extends Realm.DefaultFunctionsFactory = DefaultFunctionsFactory, + CustomDataType extends Record = Record, + UserProfileDataType extends Realm.DefaultUserProfileData = Realm.DefaultUserProfileData, >(): Realm.User => { const user = useContext(UserContext); @@ -112,5 +112,5 @@ export const useUser = < throw new Error("No user found. Did you forget to wrap your component in a ?"); } - return user as Realm.User; + return user; }; diff --git a/packages/realm-react/tsconfig.json b/packages/realm-react/tsconfig.json index ca52f9b28d..704b392644 100644 --- a/packages/realm-react/tsconfig.json +++ b/packages/realm-react/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "target": "ES2021", "module": "ES2020", + "moduleResolution": "Bundler", "lib": [ "es2021", ], @@ -10,7 +11,6 @@ "react" ], "esModuleInterop": true, - "moduleResolution": "node", "jsx": "react", "sourceMap": true, "outDir": "./dist", diff --git a/packages/realm/.eslintrc.json b/packages/realm/.eslintrc.json index f9d4a1c4e0..9f07d33114 100644 --- a/packages/realm/.eslintrc.json +++ b/packages/realm/.eslintrc.json @@ -7,6 +7,7 @@ "rules": { "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/no-duplicate-enum-values": "off", + "@typescript-eslint/consistent-type-imports": "error", "no-console": "error", "sort-imports": ["warn", { "ignoreDeclarationSort": true }], "jsdoc/check-tag-names": "off", diff --git a/packages/realm/.madgerc b/packages/realm/.madgerc new file mode 100644 index 0000000000..ffb359de70 --- /dev/null +++ b/packages/realm/.madgerc @@ -0,0 +1,11 @@ +{ + "detectiveOptions": { + "ts": { + "skipTypeImports": true + } + }, + "excludeRegExp": [ + "namespace\\.ts", + "deprecated-global\\.ts" + ] +} \ No newline at end of file diff --git a/packages/realm/package.json b/packages/realm/package.json index d837494549..e987bb5017 100644 --- a/packages/realm/package.json +++ b/packages/realm/package.json @@ -90,6 +90,7 @@ "build:node": "wireit", "bindgen:jsi": "wireit", "check-types": "wireit", + "check-circular-imports": "wireit", "install": "prebuild-install --runtime napi || echo 'Failed to download prebuild for Realm'", "docs": "wireit", "postinstall": "node ./scripts/submit-analytics.js" @@ -296,6 +297,16 @@ "build:ts" ] }, + "check-circular-imports": { + "command": "madge --circular --extensions ts src", + "dependencies": [ + "../fetch:build", + "bindgen:generate:typescript", + "bindgen:generate:node-wrapper", + "bindgen:generate:react-native-wrapper", + "bindgen:transpile" + ] + }, "docs": { "command": "typedoc", "dependencies": [ @@ -357,4 +368,4 @@ 6 ] } -} +} \ No newline at end of file diff --git a/packages/realm/src/ClassHelpers.ts b/packages/realm/src/ClassHelpers.ts index 3b0880feb2..6bc8dc6af1 100644 --- a/packages/realm/src/ClassHelpers.ts +++ b/packages/realm/src/ClassHelpers.ts @@ -16,15 +16,11 @@ // //////////////////////////////////////////////////////////////////////////// -import { - CanonicalObjectSchema, - DefaultObject, - INTERNAL_HELPERS, - PropertyMap, - RealmObject, - RealmObjectConstructor, - binding, -} from "./internal"; +import type { binding } from "../binding"; +import type { CanonicalObjectSchema, DefaultObject, RealmObjectConstructor } from "./schema"; +import type { PropertyMap } from "./PropertyMap"; +import type { RealmObject } from "./Object"; +import { OBJECT_HELPERS } from "./symbols"; type ObjectWrapper = (obj: binding.Obj) => (RealmObject & DefaultObject) | null; @@ -40,7 +36,7 @@ export type ClassHelpers = { /** @internal */ export function setClassHelpers(constructor: RealmObjectConstructor, value: ClassHelpers): void { // Store the properties map on the object class - Object.defineProperty(constructor, INTERNAL_HELPERS, { + Object.defineProperty(constructor, OBJECT_HELPERS, { enumerable: false, writable: false, configurable: false, @@ -56,7 +52,7 @@ export function setClassHelpers(constructor: RealmObjectConstructor, value: Clas * @internal */ export function getClassHelpers(arg: typeof RealmObject): ClassHelpers { - const helpers = arg[INTERNAL_HELPERS]; + const helpers = arg[OBJECT_HELPERS]; if (helpers) { return helpers as ClassHelpers; } else { diff --git a/packages/realm/src/ClassMap.ts b/packages/realm/src/ClassMap.ts index 3153561167..95679c2c66 100644 --- a/packages/realm/src/ClassMap.ts +++ b/packages/realm/src/ClassMap.ts @@ -16,22 +16,13 @@ // //////////////////////////////////////////////////////////////////////////// -import { - CanonicalObjectSchema, - Constructor, - INTERNAL, - KEY_ARRAY, - KEY_SET, - PropertyMap, - REALM, - Realm, - RealmObject, - RealmObjectConstructor, - assert, - binding, - getClassHelpers, - setClassHelpers, -} from "./internal"; +import type { CanonicalObjectSchema, Constructor, RealmObjectConstructor } from "./schema"; +import type { binding } from "../binding"; +import { PropertyMap } from "./PropertyMap"; +import { KEY_ARRAY, KEY_SET, RealmObject } from "./Object"; +import { assert } from "./assert"; +import { getClassHelpers, setClassHelpers } from "./ClassHelpers"; +import { OBJECT_INTERNAL, OBJECT_REALM } from "./symbols"; /** @internal */ export class ClassMap { @@ -81,15 +72,15 @@ export class ClassMap { Object.defineProperty(constructor.prototype, propertyName, { enumerable: true, get(this: RealmObject) { - return get(this[INTERNAL]); + return get(this[OBJECT_INTERNAL]); }, set(this: RealmObject, value: unknown) { - set(this[INTERNAL], value); + set(this[OBJECT_INTERNAL], value); }, }); } - Object.defineProperty(constructor.prototype, REALM, { + Object.defineProperty(constructor.prototype, OBJECT_REALM, { enumerable: false, configurable: false, writable: false, diff --git a/packages/realm/src/Collection.ts b/packages/realm/src/Collection.ts index 12d6b6c553..8e36cd6001 100644 --- a/packages/realm/src/Collection.ts +++ b/packages/realm/src/Collection.ts @@ -16,16 +16,18 @@ // //////////////////////////////////////////////////////////////////////////// -import type { - Dictionary, - DictionaryAccessor, - List, - OrderedCollectionAccessor, - RealmSet, - Results, - TypeHelpers, -} from "./internal"; -import { CallbackAdder, IllegalConstructorError, Listeners, TypeAssertionError, assert, binding } from "./internal"; +import type { binding } from "../binding"; +import { injectIndirect } from "./indirect"; +import type { Dictionary } from "./Dictionary"; +import type { List } from "./List"; +import type { OrderedCollectionAccessor } from "./OrderedCollection"; +import type { RealmSet } from "./Set"; +import type { Results } from "./Results"; +import type { TypeHelpers } from "./TypeHelpers"; +import { type CallbackAdder, Listeners } from "./Listeners"; +import { IllegalConstructorError, type TypeAssertionError } from "./errors"; +import { assert } from "./assert"; +import type { DictionaryAccessor } from "./collection-accessors/Dictionary"; /** * Collection accessor identifier. @@ -198,3 +200,8 @@ export abstract class Collection< this.listeners.removeAll(); } } + +/* eslint-disable-next-line @typescript-eslint/no-explicit-any -- We define these once to avoid using "any" through the code */ +export type AnyCollection = Collection; + +injectIndirect("Collection", Collection); diff --git a/packages/realm/src/Configuration.ts b/packages/realm/src/Configuration.ts index 55bc7c0fa2..76638578f0 100644 --- a/packages/realm/src/Configuration.ts +++ b/packages/realm/src/Configuration.ts @@ -16,17 +16,15 @@ // //////////////////////////////////////////////////////////////////////////// -import type { - AnyRealmObject, - AppConfiguration, - ObjectSchema, - Realm, - RealmObjectConstructor, - SyncConfiguration, - User, -} from "./internal"; - -import { TypeAssertionError, assert, validateRealmSchema, validateSyncConfiguration } from "./internal"; +import type { AnyRealmObject } from "./Object"; +import type { AppConfiguration } from "./app-services/App"; +import type { User } from "./app-services/User"; +import type { ObjectSchema, RealmObjectConstructor } from "./schema"; +import type { Realm } from "./Realm"; +import { TypeAssertionError } from "./errors"; +import { assert } from "./assert"; +import { validateRealmSchema } from "./schema"; +import { type SyncConfiguration, validateSyncConfiguration } from "./app-services/SyncConfiguration"; /** * A function which can be called to migrate a Realm from one version of the schema to another. diff --git a/packages/realm/src/Counter.ts b/packages/realm/src/Counter.ts index 9050070d61..8227c3cd05 100644 --- a/packages/realm/src/Counter.ts +++ b/packages/realm/src/Counter.ts @@ -16,7 +16,11 @@ // //////////////////////////////////////////////////////////////////////////// -import { IllegalConstructorError, Realm, UpdateMode, assert, binding } from "./internal"; +import { binding } from "../binding"; +import { assert } from "./assert"; +import { IllegalConstructorError } from "./errors"; +import type { Realm } from "./Realm"; +import type { UpdateMode } from "./Object"; const REALM = Symbol("Counter#realm"); const OBJ = Symbol("Counter#obj"); @@ -84,7 +88,7 @@ export class Counter { /** @internal */ constructor(realm: Realm, obj: binding.Obj, columnKey: binding.ColKey) { - if (!(realm instanceof Realm) || !(obj instanceof binding.Obj)) { + if (!(obj instanceof binding.Obj)) { throw new IllegalConstructorError("Counter"); } diff --git a/packages/realm/src/Dictionary.ts b/packages/realm/src/Dictionary.ts index 9bb10be828..6a5dcf6dd4 100644 --- a/packages/realm/src/Dictionary.ts +++ b/packages/realm/src/Dictionary.ts @@ -16,27 +16,19 @@ // //////////////////////////////////////////////////////////////////////////// -import { - COLLECTION_ACCESSOR as ACCESSOR, - AssertionError, - Collection, - DefaultObject, - IllegalConstructorError, - JSONCacheMap, - List, - Realm, - RealmObject, - Results, - COLLECTION_TYPE_HELPERS as TYPE_HELPERS, - TypeHelpers, - assert, - binding, - createListAccessor, - createResultsAccessor, - insertIntoListOfMixed, - isJsOrRealmList, - toItemType, -} from "./internal"; +import { assert } from "./assert"; +import { binding } from "../binding"; +import { indirect, injectIndirect } from "./indirect"; +import { COLLECTION_ACCESSOR as ACCESSOR, Collection, COLLECTION_TYPE_HELPERS as TYPE_HELPERS } from "./Collection"; +import { AssertionError, IllegalConstructorError } from "./errors"; +import type { DefaultObject } from "./schema"; +import { JSONCacheMap } from "./JSONCacheMap"; +import type { Realm } from "./Realm"; +import { toItemType } from "./TypeHelpers"; +import type { TypeHelpers } from "./TypeHelpers"; +import { RealmObject } from "./Object"; +import type { DictionaryAccessor } from "./collection-accessors/Dictionary"; +import { createResultsAccessor } from "./collection-accessors/Results"; /* eslint-disable jsdoc/multiline-blocks -- We need this to have @ts-expect-error located correctly in the .d.ts bundle */ @@ -224,7 +216,7 @@ export class Dictionary extends Collection< const itemType = toItemType(values.type); const typeHelpers = this[TYPE_HELPERS]; const accessor = createResultsAccessor({ realm, typeHelpers, itemType }); - const results = new Results(realm, values, accessor, typeHelpers); + const results = new indirect.Results(realm, values, accessor, typeHelpers); for (const value of results.values()) { yield value; @@ -246,7 +238,7 @@ export class Dictionary extends Collection< const itemType = toItemType(snapshot.type); const typeHelpers = this[TYPE_HELPERS]; const accessor = createResultsAccessor({ realm, typeHelpers, itemType }); - const results = new Results(realm, snapshot, accessor, typeHelpers); + const results = new indirect.Results(realm, snapshot, accessor, typeHelpers); for (let i = 0; i < size; i++) { const key = keys.getAny(i); @@ -333,123 +325,7 @@ export class Dictionary extends Collection< } } -/** - * Accessor for getting and setting items in the binding collection. - * @internal - */ -export type DictionaryAccessor = { - get: (dictionary: binding.Dictionary, key: string) => T; - set: (dictionary: binding.Dictionary, key: string, value: T) => void; -}; - -type DictionaryAccessorFactoryOptions = { - realm: Realm; - typeHelpers: TypeHelpers; - itemType: binding.PropertyType; - isEmbedded?: boolean; -}; - -/** @internal */ -export function createDictionaryAccessor(options: DictionaryAccessorFactoryOptions): DictionaryAccessor { - return options.itemType === binding.PropertyType.Mixed - ? createDictionaryAccessorForMixed(options) - : createDictionaryAccessorForKnownType(options); -} - -function createDictionaryAccessorForMixed({ - realm, - typeHelpers, -}: Pick, "realm" | "typeHelpers">): DictionaryAccessor { - const { toBinding, fromBinding } = typeHelpers; - return { - get(dictionary, key) { - const value = dictionary.tryGetAny(key); - switch (value) { - case binding.ListSentinel: { - const accessor = createListAccessor({ realm, itemType: binding.PropertyType.Mixed, typeHelpers }); - return new List(realm, dictionary.getList(key), accessor, typeHelpers) as T; - } - case binding.DictionarySentinel: { - const accessor = createDictionaryAccessor({ realm, itemType: binding.PropertyType.Mixed, typeHelpers }); - return new Dictionary(realm, dictionary.getDictionary(key), accessor, typeHelpers) as T; - } - default: - return fromBinding(value) as T; - } - }, - set(dictionary, key, value) { - assert.inTransaction(realm); - - if (isJsOrRealmList(value)) { - dictionary.insertCollection(key, binding.CollectionType.List); - insertIntoListOfMixed(value, dictionary.getList(key), toBinding); - } else if (isJsOrRealmDictionary(value)) { - dictionary.insertCollection(key, binding.CollectionType.Dictionary); - insertIntoDictionaryOfMixed(value, dictionary.getDictionary(key), toBinding); - } else { - dictionary.insertAny(key, toBinding(value)); - } - }, - }; -} - -function createDictionaryAccessorForKnownType({ - realm, - typeHelpers, - isEmbedded, -}: Omit, "itemType">): DictionaryAccessor { - const { fromBinding, toBinding } = typeHelpers; - return { - get(dictionary, key) { - return fromBinding(dictionary.tryGetAny(key)); - }, - set(dictionary, key, value) { - assert.inTransaction(realm); +/* eslint-disable-next-line @typescript-eslint/no-explicit-any -- We define these once to avoid using "any" through the code */ +export type AnyDictionary = Dictionary; - if (isEmbedded) { - toBinding(value, { createObj: () => [dictionary.insertEmbedded(key), true] }); - } else { - dictionary.insertAny(key, toBinding(value)); - } - }, - }; -} - -/** @internal */ -export function insertIntoDictionaryOfMixed( - dictionary: Dictionary | Record, - internal: binding.Dictionary, - toBinding: TypeHelpers["toBinding"], -) { - // TODO: Solve the "removeAll()" case for self-assignment (https://github.com/realm/realm-core/issues/7422). - internal.removeAll(); - - for (const key in dictionary) { - const value = dictionary[key]; - if (isJsOrRealmList(value)) { - internal.insertCollection(key, binding.CollectionType.List); - insertIntoListOfMixed(value, internal.getList(key), toBinding); - } else if (isJsOrRealmDictionary(value)) { - internal.insertCollection(key, binding.CollectionType.Dictionary); - insertIntoDictionaryOfMixed(value, internal.getDictionary(key), toBinding); - } else { - internal.insertAny(key, toBinding(value)); - } - } -} - -/** @internal */ -export function isJsOrRealmDictionary(value: unknown): value is Dictionary | Record { - return isPOJO(value) || value instanceof Dictionary; -} - -/** @internal */ -export function isPOJO(value: unknown): value is Record { - return ( - typeof value === "object" && - value !== null && - // Lastly check for the absence of a prototype as POJOs - // can still be created using `Object.create(null)`. - (value.constructor === Object || !Object.getPrototypeOf(value)) - ); -} +injectIndirect("Dictionary", Dictionary); diff --git a/packages/realm/src/GeoSpatial.ts b/packages/realm/src/GeoSpatial.ts index 4a4dc39340..1dbc7a982e 100644 --- a/packages/realm/src/GeoSpatial.ts +++ b/packages/realm/src/GeoSpatial.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import { binding } from "./internal"; +import { binding } from "../binding"; /** * Represents the coordinates of a point. The first two required elements of the array are longitude (index 0) and latitude (index 1). diff --git a/packages/realm/src/JSONCacheMap.ts b/packages/realm/src/JSONCacheMap.ts index 6893461601..92c36f6a20 100644 --- a/packages/realm/src/JSONCacheMap.ts +++ b/packages/realm/src/JSONCacheMap.ts @@ -16,12 +16,14 @@ // //////////////////////////////////////////////////////////////////////////// -import { DefaultObject, INTERNAL, RealmObject } from "./internal"; +import type { RealmObject } from "./Object"; +import type { DefaultObject } from "./schema"; +import { OBJECT_INTERNAL } from "./symbols"; /** @internal */ export class JSONCacheMap extends Map> { add(object: RealmObject, value: DefaultObject) { - const tableKey = object[INTERNAL].table.key; + const tableKey = object[OBJECT_INTERNAL].table.key; let cachedMap = this.get(tableKey); if (!cachedMap) { cachedMap = new Map(); @@ -30,6 +32,6 @@ export class JSONCacheMap extends Map> { cachedMap.set(object._objectKey(), value); } find(object: RealmObject) { - return this.get(object[INTERNAL].table.key)?.get(object._objectKey()); + return this.get(object[OBJECT_INTERNAL].table.key)?.get(object._objectKey()); } } diff --git a/packages/realm/src/List.ts b/packages/realm/src/List.ts index 0d1a00f7a0..9892a871ad 100644 --- a/packages/realm/src/List.ts +++ b/packages/realm/src/List.ts @@ -16,23 +16,16 @@ // //////////////////////////////////////////////////////////////////////////// -import { - COLLECTION_ACCESSOR as ACCESSOR, - AssertionError, - Dictionary, - IllegalConstructorError, - ObjectSchema, - OrderedCollection, - Realm, - TypeHelpers, - assert, - binding, - createDefaultGetter, - createDictionaryAccessor, - insertIntoDictionaryOfMixed, - isJsOrRealmDictionary, - toItemType, -} from "./internal"; +import { assert } from "./assert"; +import { binding } from "../binding"; +import { injectIndirect } from "./indirect"; +import { COLLECTION_ACCESSOR as ACCESSOR } from "./Collection"; +import { AssertionError, IllegalConstructorError } from "./errors"; +import { OrderedCollection } from "./OrderedCollection"; +import type { ObjectSchema } from "./schema"; +import type { Realm } from "./Realm"; +import { type TypeHelpers, toItemType } from "./TypeHelpers"; +import type { ListAccessor } from "./collection-accessors/List"; type PartiallyWriteableArray = Pick, "pop" | "push" | "shift" | "unshift" | "splice">; @@ -318,131 +311,7 @@ export class List } } -/** - * Accessor for getting, setting, and inserting items in the binding collection. - * @internal - */ -export type ListAccessor = { - get: (list: binding.List, index: number) => T; - set: (list: binding.List, index: number, value: T) => void; - insert: (list: binding.List, index: number, value: T) => void; -}; - -type ListAccessorFactoryOptions = { - realm: Realm; - typeHelpers: TypeHelpers; - itemType: binding.PropertyType; - isEmbedded?: boolean; -}; - -/** @internal */ -export function createListAccessor(options: ListAccessorFactoryOptions): ListAccessor { - return options.itemType === binding.PropertyType.Mixed - ? createListAccessorForMixed(options) - : createListAccessorForKnownType(options); -} - -function createListAccessorForMixed({ - realm, - typeHelpers, -}: Pick, "realm" | "typeHelpers">): ListAccessor { - const { toBinding } = typeHelpers; - return { - get(list, index) { - const value = list.getAny(index); - switch (value) { - case binding.ListSentinel: { - const accessor = createListAccessor({ realm, typeHelpers, itemType: binding.PropertyType.Mixed }); - return new List(realm, list.getList(index), accessor, typeHelpers) as T; - } - case binding.DictionarySentinel: { - const accessor = createDictionaryAccessor({ realm, typeHelpers, itemType: binding.PropertyType.Mixed }); - return new Dictionary(realm, list.getDictionary(index), accessor, typeHelpers) as T; - } - default: - return typeHelpers.fromBinding(value); - } - }, - set(list, index, value) { - assert.inTransaction(realm); - - if (isJsOrRealmList(value)) { - list.setCollection(index, binding.CollectionType.List); - insertIntoListOfMixed(value, list.getList(index), toBinding); - } else if (isJsOrRealmDictionary(value)) { - list.setCollection(index, binding.CollectionType.Dictionary); - insertIntoDictionaryOfMixed(value, list.getDictionary(index), toBinding); - } else { - list.setAny(index, toBinding(value)); - } - }, - insert(list, index, value) { - assert.inTransaction(realm); - - if (isJsOrRealmList(value)) { - list.insertCollection(index, binding.CollectionType.List); - insertIntoListOfMixed(value, list.getList(index), toBinding); - } else if (isJsOrRealmDictionary(value)) { - list.insertCollection(index, binding.CollectionType.Dictionary); - insertIntoDictionaryOfMixed(value, list.getDictionary(index), toBinding); - } else { - list.insertAny(index, toBinding(value)); - } - }, - }; -} +/* eslint-disable-next-line @typescript-eslint/no-explicit-any -- We define these once to avoid using "any" through the code */ +export type AnyList = List; -function createListAccessorForKnownType({ - realm, - typeHelpers, - itemType, - isEmbedded, -}: Omit, "isMixed">): ListAccessor { - const { fromBinding, toBinding } = typeHelpers; - return { - get: createDefaultGetter({ fromBinding, itemType }), - set(list, index, value) { - assert.inTransaction(realm); - list.setAny( - index, - toBinding(value, isEmbedded ? { createObj: () => [list.setEmbedded(index), true] } : undefined), - ); - }, - insert(list, index, value) { - assert.inTransaction(realm); - if (isEmbedded) { - // Simply transforming to binding will insert the embedded object - toBinding(value, { createObj: () => [list.insertEmbedded(index), true] }); - } else { - list.insertAny(index, toBinding(value)); - } - }, - }; -} - -/** @internal */ -export function insertIntoListOfMixed( - list: List | unknown[], - internal: binding.List, - toBinding: TypeHelpers["toBinding"], -) { - // TODO: Solve the "removeAll()" case for self-assignment (https://github.com/realm/realm-core/issues/7422). - internal.removeAll(); - - for (const [index, item] of list.entries()) { - if (isJsOrRealmList(item)) { - internal.insertCollection(index, binding.CollectionType.List); - insertIntoListOfMixed(item, internal.getList(index), toBinding); - } else if (isJsOrRealmDictionary(item)) { - internal.insertCollection(index, binding.CollectionType.Dictionary); - insertIntoDictionaryOfMixed(item, internal.getDictionary(index), toBinding); - } else { - internal.insertAny(index, toBinding(item)); - } - } -} - -/** @internal */ -export function isJsOrRealmList(value: unknown): value is List | unknown[] { - return Array.isArray(value) || value instanceof List; -} +injectIndirect("List", List); diff --git a/packages/realm/src/Logger.ts b/packages/realm/src/Logger.ts index 3c0c91ba85..a27ecf45e7 100644 --- a/packages/realm/src/Logger.ts +++ b/packages/realm/src/Logger.ts @@ -16,7 +16,9 @@ // //////////////////////////////////////////////////////////////////////////// -import { type App, assert, binding } from "./internal"; +import { binding } from "../binding"; +import { assert } from "./assert"; +import type { App } from "./app-services/App"; export type LogLevel = "all" | "trace" | "debug" | "detail" | "info" | "warn" | "error" | "fatal" | "off"; diff --git a/packages/realm/src/Object.ts b/packages/realm/src/Object.ts index 4e96620f0e..a93a17d778 100644 --- a/packages/realm/src/Object.ts +++ b/packages/realm/src/Object.ts @@ -16,33 +16,30 @@ // //////////////////////////////////////////////////////////////////////////// +import { binding } from "../binding"; +import { assert } from "./assert"; +import { AssertionError, TypeAssertionError } from "./errors"; +import { indirect, injectIndirect } from "./indirect"; +import { BSON } from "./bson"; import { - AssertionError, - BSON, - CanonicalObjectSchema, - ClassHelpers, - type Collection, - Constructor, - DefaultObject, - Dictionary, - JSONCacheMap, - ObjectChangeCallback, - ObjectListeners, - ObjectSchema, - OmittedRealmTypes, - OrderedCollection, - Realm, - RealmObjectConstructor, - Results, - TypeAssertionError, - TypeHelpers, - Unmanaged, - assert, - binding, - createResultsAccessor, - flags, + type CanonicalObjectSchema, + type Constructor, + type DefaultObject, + type ObjectSchema, + type RealmObjectConstructor, getTypeName, -} from "./internal"; +} from "./schema"; +import type { ClassHelpers } from "./ClassHelpers"; +import type { Collection } from "./Collection"; +import { JSONCacheMap } from "./JSONCacheMap"; +import { type ObjectChangeCallback, ObjectListeners } from "./ObjectListeners"; +import type { OmittedRealmTypes, Unmanaged } from "./Unmanaged"; +import type { Realm } from "./Realm"; +import type { Results } from "./Results"; +import type { TypeHelpers } from "./TypeHelpers"; +import { flags } from "./flags"; +import { OBJECT_HELPERS, OBJECT_INTERNAL, OBJECT_REALM } from "./symbols"; +import { createResultsAccessor } from "./collection-accessors/Results"; /** * The update mode to use when creating an object that already exists, @@ -83,10 +80,7 @@ export type AnyRealmObject = RealmObject; export const KEY_ARRAY = Symbol("Object#keys"); export const KEY_SET = Symbol("Object#keySet"); -export const REALM = Symbol("Object#realm"); -export const INTERNAL = Symbol("Object#internal"); const INTERNAL_LISTENERS = Symbol("Object#listeners"); -export const INTERNAL_HELPERS = Symbol("Object.helpers"); const DEFAULT_PROPERTY_DESCRIPTOR: PropertyDescriptor = { configurable: true, enumerable: true, writable: true }; /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ @@ -100,7 +94,7 @@ const PROXY_HANDLER: ProxyHandler> = { } const result = Reflect.getOwnPropertyDescriptor(target, prop); if (result && typeof prop === "symbol") { - if (prop === INTERNAL) { + if (prop === OBJECT_INTERNAL) { result.enumerable = false; result.writable = false; } else if (prop === INTERNAL_LISTENERS) { @@ -159,7 +153,7 @@ export class RealmObject(internal: binding.Obj, constructor: Constructor): RealmObject & T { const result = Object.create(constructor.prototype); - result[INTERNAL] = internal; + result[OBJECT_INTERNAL] = internal; // Initializing INTERNAL_LISTENERS here rather than letting it just be implicitly undefined since JS engines // prefer adding all fields to objects upfront. Adding optional fields later can sometimes trigger deoptimizations. result[INTERNAL_LISTENERS] = null; @@ -333,13 +327,13 @@ export class RealmObject { - return this[REALM].getClassHelpers(this).canonicalObjectSchema as CanonicalObjectSchema; + return this[OBJECT_REALM].getClassHelpers(this).canonicalObjectSchema as CanonicalObjectSchema; } /** @@ -437,7 +435,7 @@ export class RealmObject(objectType: string, propertyName: string): Results & T>; linkingObjects(objectType: Constructor, propertyName: string): Results; linkingObjects(objectType: string | Constructor, propertyName: string): Results { - const realm = this[REALM]; + const realm = this[OBJECT_REALM]; const targetClassHelpers = realm.getClassHelpers(objectType); const { objectSchema: targetObjectSchema, properties, wrapObject } = targetClassHelpers; const targetProperty = properties.get(propertyName); @@ -462,10 +460,10 @@ export class RealmObject(realm, results, accessor, typeHelpers); + return new indirect.Results(realm, results, accessor, typeHelpers); } /** @@ -473,7 +471,7 @@ export class RealmObject, keyPaths?: string | string[]): void { assert.function(callback); if (!this[INTERNAL_LISTENERS]) { - this[INTERNAL_LISTENERS] = new ObjectListeners(this[REALM].internal, this); + this[INTERNAL_LISTENERS] = new ObjectListeners(this[OBJECT_REALM].internal, this); } this[INTERNAL_LISTENERS].addListener(callback, typeof keyPaths === "string" ? [keyPaths] : keyPaths); } @@ -549,12 +547,12 @@ export class RealmObject`; } else if (value instanceof binding.ObjLink) { - const { objectSchema } = this[REALM].getClassHelpers(value.tableKey); + const { objectSchema } = this[OBJECT_REALM].getClassHelpers(value.tableKey); return `<${objectSchema.name}>`; } else if (value instanceof ArrayBuffer) { return "data"; @@ -601,3 +599,5 @@ export class RealmObject = { /** @@ -88,7 +93,7 @@ export class ObjectListeners { if (notifier) { return notifier; } else { - notifier = binding.Helpers.makeObjectNotifier(this.realm, this.object[INTERNAL]); + notifier = binding.Helpers.makeObjectNotifier(this.realm, this.object[OBJECT_INTERNAL]); this.internal = notifier; return notifier; } diff --git a/packages/realm/src/OrderedCollection.ts b/packages/realm/src/OrderedCollection.ts index 59b0407620..9f8cdd842c 100644 --- a/packages/realm/src/OrderedCollection.ts +++ b/packages/realm/src/OrderedCollection.ts @@ -16,36 +16,32 @@ // //////////////////////////////////////////////////////////////////////////// -import { - ClassHelpers, - Collection, - DefaultObject, - IllegalConstructorError, - JSONCacheMap, - ListAccessor, - INTERNAL as OBJ_INTERNAL, - Realm, - RealmObject, - Results, - ResultsAccessor, - SetAccessor, - COLLECTION_TYPE_HELPERS as TYPE_HELPERS, - TypeAssertionError, - TypeHelpers, - assert, - binding, - createResultsAccessor, - getTypeName, - isJsOrRealmDictionary, - isJsOrRealmList, - mixedToBinding, - toItemType, - unwind, -} from "./internal"; +import { binding } from "../binding"; +import { assert } from "./assert"; +import { IllegalConstructorError, TypeAssertionError } from "./errors"; +import { indirect, injectIndirect } from "./indirect"; +import type { ClassHelpers } from "./ClassHelpers"; +import { Collection, COLLECTION_TYPE_HELPERS as TYPE_HELPERS } from "./Collection"; +import type { DefaultObject } from "./schema"; +import { JSONCacheMap } from "./JSONCacheMap"; +import type { Results } from "./Results"; +import { RealmObject } from "./Object"; +import { type TypeHelpers, toItemType } from "./TypeHelpers"; +import { getTypeName } from "./schema"; +import { unwind } from "./ranges"; +import type { Realm } from "./Realm"; +import { mixedToBinding } from "./type-helpers/Mixed"; +import { OBJECT_INTERNAL } from "./symbols"; +import type { ListAccessor } from "./collection-accessors/List"; +import { type ResultsAccessor, createResultsAccessor } from "./collection-accessors/Results"; +import type { SetAccessor } from "./collection-accessors/Set"; + +const INDEX_NOT_FOUND = -1; const DEFAULT_COLUMN_KEY = binding.Int64.numToInt(0) as unknown as binding.ColKey; -type OrderedCollectionInternal = binding.List | binding.Results | binding.Set; +/** @internal */ +export type OrderedCollectionInternal = binding.List | binding.Results | binding.Set; type PropertyType = string; /** @@ -116,7 +112,7 @@ const PROXY_HANDLER: ProxyHandler = { } catch (err) { // Let the custom errors from Results take precedence over out of bounds errors. This will // let users know that they cannot modify Results, rather than erroring on incorrect index. - if (index < 0 && !(target instanceof Results)) { + if (index < 0 && !(target instanceof indirect.Results)) { throw new Error(`Cannot set item at negative index ${index}.`); } throw err; @@ -404,14 +400,14 @@ export abstract class OrderedCollection< if (this.type === "object") { assert.instanceOf(searchElement, RealmObject); - return this.results.indexOfObj(searchElement[OBJ_INTERNAL]); - } else if (isJsOrRealmList(searchElement) || isJsOrRealmDictionary(searchElement)) { - // Collections are always treated as not equal since their - // references will always be different for each access. - const NOT_FOUND = -1; - return NOT_FOUND; + return this.results.indexOfObj(searchElement[OBJECT_INTERNAL]); } else { - return this.results.indexOf(this[TYPE_HELPERS].toBinding(searchElement)); + try { + return this.results.indexOf(this[TYPE_HELPERS].toBinding(searchElement)); + } catch { + // Inability to convert to the binding representation means we won't be able to find it. + return INDEX_NOT_FOUND; + } } } /** @@ -832,7 +828,7 @@ export abstract class OrderedCollection< const itemType = toItemType(results.type); const typeHelpers = this[TYPE_HELPERS]; const accessor = createResultsAccessor({ realm, typeHelpers, itemType }); - return new Results(realm, results, accessor, typeHelpers); + return new indirect.Results(realm, results, accessor, typeHelpers); } /** @internal */ @@ -922,7 +918,7 @@ export abstract class OrderedCollection< const itemType = toItemType(results.type); const typeHelpers = this[TYPE_HELPERS]; const accessor = createResultsAccessor({ realm, typeHelpers, itemType }); - return new Results(realm, results, accessor, typeHelpers); + return new indirect.Results(realm, results, accessor, typeHelpers); } else if (typeof arg0 === "string") { return this.sorted([[arg0, arg1 === true]]); } else if (typeof arg0 === "boolean") { @@ -952,7 +948,7 @@ export abstract class OrderedCollection< const itemType = toItemType(snapshot.type); const typeHelpers = this[TYPE_HELPERS]; const accessor = createResultsAccessor({ realm, typeHelpers, itemType }); - return new Results(realm, snapshot, accessor, typeHelpers); + return new indirect.Results(realm, snapshot, accessor, typeHelpers); } /** @internal */ @@ -973,34 +969,4 @@ export abstract class OrderedCollection< } } -type Getter = (collection: CollectionType, index: number) => T; - -type GetterFactoryOptions = { - fromBinding: TypeHelpers["fromBinding"]; - itemType: binding.PropertyType; -}; - -/** @internal */ -export function createDefaultGetter({ - fromBinding, - itemType, -}: GetterFactoryOptions): Getter { - const isObjectItem = itemType === binding.PropertyType.Object || itemType === binding.PropertyType.LinkingObjects; - return isObjectItem ? (...args) => getObject(fromBinding, ...args) : (...args) => getKnownType(fromBinding, ...args); -} - -function getObject( - fromBinding: TypeHelpers["fromBinding"], - collection: OrderedCollectionInternal, - index: number, -): T { - return fromBinding(collection.getObj(index)); -} - -function getKnownType( - fromBinding: TypeHelpers["fromBinding"], - collection: OrderedCollectionInternal, - index: number, -): T { - return fromBinding(collection.getAny(index)); -} +injectIndirect("OrderedCollection", OrderedCollection); diff --git a/packages/realm/src/ProgressRealmPromise.ts b/packages/realm/src/ProgressRealmPromise.ts index 93721f9ff7..f8de18938c 100644 --- a/packages/realm/src/ProgressRealmPromise.ts +++ b/packages/realm/src/ProgressRealmPromise.ts @@ -16,22 +16,18 @@ // //////////////////////////////////////////////////////////////////////////// -import { - Configuration, - OpenRealmBehaviorType, - OpenRealmTimeOutBehavior, - ProgressNotificationCallback, - PromiseHandle, - Realm, - SubscriptionSetState, - TimeoutError, - TimeoutPromise, - assert, - binding, - flags, - isEstimateProgressNotificationCallback, - validateConfiguration, -} from "./internal"; +import { binding } from "../binding"; +import { assert } from "./assert"; +import { TimeoutError } from "./errors"; +import { flags } from "./flags"; +import { indirect } from "./indirect"; +import { type Configuration, validateConfiguration } from "./Configuration"; +import { OpenRealmBehaviorType, OpenRealmTimeOutBehavior } from "./app-services/SyncConfiguration"; +import { SubscriptionSetState } from "./app-services/BaseSubscriptionSet"; +import { type ProgressNotificationCallback, isEstimateProgressNotificationCallback } from "./app-services/SyncSession"; +import { PromiseHandle } from "./PromiseHandle"; +import { TimeoutPromise } from "./TimeoutPromise"; +import type { Realm } from "./Realm"; type OpenBehavior = { openBehavior: OpenRealmBehaviorType; @@ -99,13 +95,13 @@ export class ProgressRealmPromise implements Promise { // Calling `Realm.exists()` before `binding.Realm.getSynchronizedRealm()` is necessary to capture // the correct value when this constructor was called since `binding.Realm.getSynchronizedRealm()` // will open the realm. This is needed when calling the Realm constructor. - const realmExists = Realm.exists(config); + const realmExists = indirect.Realm.exists(config); const { openBehavior, timeOut, timeOutBehavior } = determineBehavior(config, realmExists); if (openBehavior === OpenRealmBehaviorType.OpenImmediately) { - const realm = new Realm(config); + const realm = new indirect.Realm(config); this.handle.resolve(realm); } else if (openBehavior === OpenRealmBehaviorType.DownloadBeforeOpen) { - const { bindingConfig } = Realm.transformConfig(config); + const { bindingConfig } = indirect.Realm.transformConfig(config); // Construct an async open task this.task = binding.Realm.getSynchronizedRealm(bindingConfig); @@ -118,7 +114,7 @@ export class ProgressRealmPromise implements Promise { this.task .start() .then(async (tsr) => { - const realm = new Realm(config, { + const realm = new indirect.Realm(config, { internal: binding.Helpers.consumeThreadSafeReferenceToSharedRealm(tsr), // Do not call `Realm.exists()` here in case the realm has been opened by this point in time. realmExists, @@ -222,7 +218,7 @@ export class ProgressRealmPromise implements Promise { this.timeoutPromise.catch((err) => { if (err instanceof TimeoutError) { this.cancelAndResetTask(); - const realm = new Realm(config); + const realm = new indirect.Realm(config); this.handle.resolve(realm); } else { this.handle.reject(err); diff --git a/packages/realm/src/PromiseHandle.ts b/packages/realm/src/PromiseHandle.ts index 38e28104ba..c04ddd18ed 100644 --- a/packages/realm/src/PromiseHandle.ts +++ b/packages/realm/src/PromiseHandle.ts @@ -16,11 +16,14 @@ // //////////////////////////////////////////////////////////////////////////// -import { assert } from "./internal"; +import { assert } from "./assert"; type ResolveType = (value: T | PromiseLike) => void; type RejectType = (reason?: T) => void; +/** + * Cross-platform alternative to `Promise.withResolvers()`. + */ export class PromiseHandle { resolve!: ResolveType; reject!: RejectType; diff --git a/packages/realm/src/PropertyHelpers.ts b/packages/realm/src/PropertyHelpers.ts index 98a8b16818..4ed1125af3 100644 --- a/packages/realm/src/PropertyHelpers.ts +++ b/packages/realm/src/PropertyHelpers.ts @@ -16,7 +16,8 @@ // //////////////////////////////////////////////////////////////////////////// -import { TypeOptions, binding, getTypeHelpers, toItemType } from "./internal"; +import { binding } from "../binding"; +import { type TypeOptions, getTypeHelpers, toItemType } from "./TypeHelpers"; import { createArrayPropertyAccessor } from "./property-accessors/Array"; import { createObjectPropertyAccessor } from "./property-accessors/Object"; @@ -25,7 +26,7 @@ import { createSetPropertyAccessor } from "./property-accessors/Set"; import { createIntPropertyAccessor } from "./property-accessors/Int"; import { createMixedPropertyAccessor } from "./property-accessors/Mixed"; import { createDefaultPropertyAccessor } from "./property-accessors/default"; -import { +import type { HelperOptions, PropertyAccessor, PropertyContext, diff --git a/packages/realm/src/PropertyMap.ts b/packages/realm/src/PropertyMap.ts index 9ab496c4d7..e547071978 100644 --- a/packages/realm/src/PropertyMap.ts +++ b/packages/realm/src/PropertyMap.ts @@ -16,8 +16,11 @@ // //////////////////////////////////////////////////////////////////////////// -import { CanonicalObjectSchema, assert, binding, createPropertyHelpers } from "./internal"; -import { HelperOptions, PropertyHelpers } from "./property-accessors/types"; +import { binding } from "../binding"; +import { assert } from "./assert"; +import type { CanonicalObjectSchema } from "./schema"; +import { createPropertyHelpers } from "./PropertyHelpers"; +import type { HelperOptions, PropertyHelpers } from "./property-accessors/types"; class UninitializedPropertyMapError extends Error { constructor() { diff --git a/packages/realm/src/Realm.ts b/packages/realm/src/Realm.ts index 4e33af4f27..536c6c5fcb 100644 --- a/packages/realm/src/Realm.ts +++ b/packages/realm/src/Realm.ts @@ -16,63 +16,56 @@ // //////////////////////////////////////////////////////////////////////////// +import { binding } from "../binding"; +import { assert } from "./assert"; +import { TypeAssertionError } from "./errors"; +import { extendDebug } from "./debug"; +import { flags } from "./flags"; +import { injectIndirect } from "./indirect"; +import { fs, garbageCollection } from "./platform"; +import type { Unmanaged } from "./Unmanaged"; +import { type AnyRealmObject, RealmObject } from "./Object"; +import { type AnyResults, Results } from "./Results"; import { - AnyList, - AnyRealmObject, - AnyResults, - CanonicalObjectSchema, - ClassHelpers, - ClassMap, - Configuration, - Constructor, - DefaultObject, - INTERNAL, - InitialSubscriptions, - LOG_CATEGORIES, - List, - LogCategory, - LogLevel, - LoggerCallback, - LoggerCallback1, - LoggerCallback2, - MigrationCallback, - ObjectSchema, - PresentationPropertyTypeName, - ProgressRealmPromise, - REALM, - RealmEvent, - RealmListenerCallback, - RealmListeners, - RealmObject, - RealmObjectConstructor, - Results, - SubscriptionSet, - SyncSession, - TypeAssertionError, - TypeHelpers, - Unmanaged, - UpdateMode, - assert, - binding, - createResultsAccessor, - defaultLogger, - defaultLoggerLevel, - extendDebug, - flags, + type CanonicalObjectSchema, + type Constructor, + type DefaultObject, + type ObjectSchema, + type PresentationPropertyTypeName, + type RealmObjectConstructor, fromBindingRealmSchema, - fs, - garbageCollection, normalizeObjectSchema, normalizeRealmSchema, - toArrayBuffer, - toBindingLogger, - toBindingLoggerLevel, toBindingSchema, - toBindingSyncConfig, - validateConfiguration, validateObjectSchema, validateRealmSchema, -} from "./internal"; +} from "./schema"; +import type { ClassHelpers } from "./ClassHelpers"; +import { ClassMap } from "./ClassMap"; +import { type Configuration, type MigrationCallback, validateConfiguration } from "./Configuration"; +import { type InitialSubscriptions, toBindingSyncConfig } from "./app-services/SyncConfiguration"; +import { + LOG_CATEGORIES, + type LogCategory, + type LogLevel, + type LoggerCallback, + type LoggerCallback1, + type LoggerCallback2, + defaultLogger, + defaultLoggerLevel, + toBindingLogger, + toBindingLoggerLevel, +} from "./Logger"; +import { type AnyList, List } from "./List"; +import { ProgressRealmPromise } from "./ProgressRealmPromise"; +import { UpdateMode } from "./Object"; +import { RealmEvent, type RealmListenerCallback, RealmListeners } from "./RealmListeners"; +import { SubscriptionSet } from "./app-services/SubscriptionSet"; +import { SyncSession } from "./app-services/SyncSession"; +import type { TypeHelpers } from "./TypeHelpers"; +import { toArrayBuffer } from "./type-helpers/array-buffer"; +import { OBJECT_INTERNAL, OBJECT_REALM } from "./symbols"; +import { createResultsAccessor } from "./collection-accessors/Results"; const debug = extendDebug("Realm"); @@ -778,7 +771,7 @@ export class Realm { mode = UpdateMode.Never; } // Implements https://github.com/realm/realm-js/blob/v11/src/js_realm.hpp#L1260-L1321 - if (values instanceof RealmObject && !values[INTERNAL]) { + if (values instanceof RealmObject && !values[OBJECT_INTERNAL]) { throw new Error("Cannot create an object from a detached RealmObject instance"); } if (!Object.values(UpdateMode).includes(mode)) { @@ -810,9 +803,9 @@ export class Realm { assert.inTransaction(this, "Can only delete objects within a transaction."); assert.object(subject, "subject"); if (subject instanceof RealmObject) { - assert.isSameRealm(subject[REALM].internal, this.internal, "Can't delete an object from another Realm"); + assert.isSameRealm(subject[OBJECT_REALM].internal, this.internal, "Can't delete an object from another Realm"); const { objectSchema } = this.classes.getHelpers(subject); - const obj = subject[INTERNAL]; + const obj = subject[OBJECT_INTERNAL]; assert.isValid( obj, "Object is invalid. Either it has been previously deleted or the Realm it belongs to has been closed.", @@ -827,10 +820,10 @@ export class Realm { //@ts-expect-error the above check is good enough for (const object of subject) { assert.instanceOf(object, RealmObject); - assert.isSameRealm(object[REALM].internal, this.internal, "Can't delete an object from another Realm"); + assert.isSameRealm(object[OBJECT_REALM].internal, this.internal, "Can't delete an object from another Realm"); const { objectSchema } = this.classes.getHelpers(object); const table = binding.Helpers.getTable(this.internal, objectSchema.tableKey); - table.removeObject(object[INTERNAL].key); + table.removeObject(object[OBJECT_INTERNAL].key); } } else { throw new Error("Can only delete objects, lists and results."); @@ -968,7 +961,7 @@ export class Realm { }, toBinding(value) { assert.instanceOf(value, RealmObject); - return value[INTERNAL]; + return value[OBJECT_INTERNAL]; }, }; const accessor = createResultsAccessor({ realm: this, typeHelpers, itemType: binding.PropertyType.Object }); @@ -1194,6 +1187,8 @@ export class Realm { } } +injectIndirect("Realm", Realm); + /** * @param objectSchema - The schema of the object. * @returns `true` if the object is marked for asymmetric sync, otherwise `false`. @@ -1214,178 +1209,179 @@ function isEmbedded(objectSchema: binding.ObjectSchema): boolean { // This declaration needs to happen in the same file which declares "Realm" // @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-namespaces-with-classes-functions-and-enums -import * as internal from "./internal"; +import * as ns from "./namespace"; + // Needed to avoid complaints about a self-reference import RealmItself = Realm; // eslint-disable-next-line @typescript-eslint/no-namespace export namespace Realm { export import Realm = RealmItself; - export import flags = internal.flags; - - export import Object = internal.RealmObject; - export import App = internal.App; - export import Auth = internal.Auth; - export import BSON = internal.BSON; - export import Types = internal.Types; - export import Services = internal.Services; - - export import index = internal.index; - export import mapTo = internal.mapTo; - export import kmToRadians = internal.kmToRadians; - export import miToRadians = internal.miToRadians; - - export import AnyCollection = internal.AnyCollection; - export import AnyDictionary = internal.AnyDictionary; - export import AnyList = internal.AnyList; - export import AnyRealmObject = internal.AnyRealmObject; - export import AnyResults = internal.AnyResults; - export import AnySet = internal.AnySet; - export import AnyUser = internal.AnyUser; - export import ApiKey = internal.ApiKey; - export import AppChangeCallback = internal.AppChangeCallback; - export import AssertionError = internal.AssertionError; - export import AppConfiguration = internal.AppConfiguration; - export import AppServicesFunction = internal.AppServicesFunction; - export import BaseConfiguration = internal.BaseConfiguration; - export import BaseObjectSchema = internal.BaseObjectSchema; - export import BaseSyncConfiguration = internal.BaseSyncConfiguration; - export import CanonicalGeoPoint = internal.CanonicalGeoPoint; - export import CanonicalGeoPolygon = internal.CanonicalGeoPolygon; - export import CanonicalObjectSchema = internal.CanonicalObjectSchema; - export import CanonicalPropertiesTypes = internal.CanonicalPropertiesTypes; - export import CanonicalPropertySchema = internal.CanonicalPropertySchema; - export import ClientResetAfterCallback = internal.ClientResetAfterCallback; - export import ClientResetBeforeCallback = internal.ClientResetBeforeCallback; - export import ClientResetConfig = internal.ClientResetConfig; - export import ClientResetDiscardUnsyncedChangesConfiguration = internal.ClientResetDiscardUnsyncedChangesConfiguration; - export import ClientResetFallbackCallback = internal.ClientResetFallbackCallback; - export import ClientResetManualConfiguration = internal.ClientResetManualConfiguration; - export import ClientResetMode = internal.ClientResetMode; - export import ClientResetRecoverOrDiscardUnsyncedChangesConfiguration = internal.ClientResetRecoverOrDiscardUnsyncedChangesConfiguration; - export import ClientResetRecoverUnsyncedChangesConfiguration = internal.ClientResetRecoverUnsyncedChangesConfiguration; - export import Collection = internal.Collection; - export import CollectionChangeCallback = internal.CollectionChangeCallback; - export import CollectionChangeSet = internal.CollectionChangeSet; - export import CollectionPropertyTypeName = internal.CollectionPropertyTypeName; - export import CompensatingWriteError = internal.CompensatingWriteError; - export import CompensatingWriteInfo = internal.CompensatingWriteInfo; - export import Configuration = internal.Configuration; - export import ConfigurationWithoutSync = internal.ConfigurationWithoutSync; - export import ConfigurationWithSync = internal.ConfigurationWithSync; - export import ConnectionNotificationCallback = internal.ConnectionNotificationCallback; - export import ConnectionState = internal.ConnectionState; - export import Counter = internal.Counter; - export import Credentials = internal.Credentials; - export import DefaultFunctionsFactory = internal.DefaultFunctionsFactory; - export import DefaultUserProfileData = internal.DefaultUserProfileData; - export import Dictionary = internal.Dictionary; - export import DictionaryChangeCallback = internal.DictionaryChangeCallback; - export import DictionaryChangeSet = internal.DictionaryChangeSet; - export import ErrorCallback = internal.ErrorCallback; - export import EstimateProgressNotificationCallback = internal.EstimateProgressNotificationCallback; - export import FlexibleSyncConfiguration = internal.FlexibleSyncConfiguration; - export import GeoBox = internal.GeoBox; - export import GeoCircle = internal.GeoCircle; - export import GeoPoint = internal.GeoPoint; - export import GeoPolygon = internal.GeoPolygon; - export import GeoPosition = internal.GeoPosition; - export import IndexDecorator = internal.IndexDecorator; - export import IndexedType = internal.IndexedType; - export import InitialSubscriptions = internal.InitialSubscriptions; - export import List = internal.List; - export import LocalAppConfiguration = internal.LocalAppConfiguration; - export import LogCategory = internal.LogCategory; - export import LogEntry = internal.LogEntry; - export import Logger = internal.Logger; - export import LoggerCallback = internal.LoggerCallback; - export import LoggerCallback1 = internal.LoggerCallback1; - export import LoggerCallback2 = internal.LoggerCallback2; - export import MapToDecorator = internal.MapToDecorator; - export import Metadata = internal.Metadata; - export import MetadataMode = internal.MetadataMode; - export import MigrationCallback = internal.MigrationCallback; - export import MigrationOptions = internal.MigrationOptions; - export import Mixed = internal.Types.Mixed; - export import MongoDB = internal.MongoDB; - export import MongoDBService = internal.MongoDBService; - export import NumericLogLevel = internal.NumericLogLevel; - export import ObjectChangeCallback = internal.ObjectChangeCallback; - export import ObjectChangeSet = internal.ObjectChangeSet; - export import ObjectSchema = internal.ObjectSchema; - export import ObjectType = internal.ObjectType; - export import OpenRealmBehaviorConfiguration = internal.OpenRealmBehaviorConfiguration; - export import OpenRealmBehaviorType = internal.OpenRealmBehaviorType; - export import OpenRealmTimeOutBehavior = internal.OpenRealmTimeOutBehavior; - export import OrderedCollection = internal.OrderedCollection; - export import PartitionSyncConfiguration = internal.PartitionSyncConfiguration; - export import PresentationPropertyTypeName = internal.PresentationPropertyTypeName; - export import PrimaryKey = internal.PrimaryKey; - export import PrimitivePropertyTypeName = internal.PrimitivePropertyTypeName; - export import ProgressDirection = internal.ProgressDirection; - export import ProgressMode = internal.ProgressMode; - export import ProgressNotificationCallback = internal.ProgressNotificationCallback; - export import ProgressRealmPromise = internal.ProgressRealmPromise; - export import PropertiesTypes = internal.PropertiesTypes; - export import PropertySchema = internal.PropertySchema; - export import PropertySchemaCommon = internal.PropertySchemaCommon; - export import PropertySchemaParseError = internal.PropertySchemaParseError; - export import PropertySchemaShorthand = internal.PropertySchemaShorthand; - export import PropertySchemaStrict = internal.PropertySchemaStrict; - export import PropertyTypeName = internal.PropertyTypeName; - export import ProviderType = internal.ProviderType; - export import ProxyType = internal.ProxyType; - export import RealmEvent = internal.RealmEvent; - export import RealmEventName = internal.RealmEventName; - export import RealmListenerCallback = internal.RealmListenerCallback; - export import RealmObjectConstructor = internal.RealmObjectConstructor; - export import RelationshipPropertyTypeName = internal.RelationshipPropertyTypeName; - export import Results = internal.Results; - export import SchemaParseError = internal.SchemaParseError; - export import SecretApiKey = internal.SecretApiKey; - export import SessionState = internal.SessionState; - export import SessionStopPolicy = internal.SessionStopPolicy; - export import Set = internal.RealmSet; - export import ShorthandPrimitivePropertyTypeName = internal.ShorthandPrimitivePropertyTypeName; - export import SortDescriptor = internal.SortDescriptor; - export import SSLConfiguration = internal.SSLConfiguration; - export import SSLVerifyCallback = internal.SSLVerifyCallback; - export import SSLVerifyObject = internal.SSLVerifyObject; - export import SubscriptionSetState = internal.SubscriptionSetState; - export import SyncConfiguration = internal.SyncConfiguration; - export import SyncError = internal.SyncError; - export import SyncProxyConfig = internal.SyncProxyConfig; - export import TypeAssertionError = internal.TypeAssertionError; - export import Unmanaged = internal.Unmanaged; - export import UpdateMode = internal.UpdateMode; - export import User = internal.User; - export import UserChangeCallback = internal.UserChangeCallback; - export import UserIdentity = internal.UserIdentity; - export import UserState = internal.UserState; - export import UserTypeName = internal.UserTypeName; - export import WaitForSync = internal.WaitForSync; - export import WatchOptionsFilter = internal.WatchOptionsFilter; - export import WatchOptionsIds = internal.WatchOptionsIds; + export import flags = ns.flags; + + export import Object = ns.RealmObject; + export import App = ns.App; + export import Auth = ns.Auth; + export import BSON = ns.BSON; + export import Types = ns.Types; + export import Services = ns.Services; + + export import index = ns.index; + export import mapTo = ns.mapTo; + export import kmToRadians = ns.kmToRadians; + export import miToRadians = ns.miToRadians; + + export import AnyCollection = ns.AnyCollection; + export import AnyDictionary = ns.AnyDictionary; + export import AnyList = ns.AnyList; + export import AnyRealmObject = ns.AnyRealmObject; + export import AnyResults = ns.AnyResults; + export import AnySet = ns.AnySet; + export import AnyUser = ns.AnyUser; + export import ApiKey = ns.ApiKey; + export import AppChangeCallback = ns.AppChangeCallback; + export import AssertionError = ns.AssertionError; + export import AppConfiguration = ns.AppConfiguration; + export import AppServicesFunction = ns.AppServicesFunction; + export import BaseConfiguration = ns.BaseConfiguration; + export import BaseObjectSchema = ns.BaseObjectSchema; + export import BaseSyncConfiguration = ns.BaseSyncConfiguration; + export import CanonicalGeoPoint = ns.CanonicalGeoPoint; + export import CanonicalGeoPolygon = ns.CanonicalGeoPolygon; + export import CanonicalObjectSchema = ns.CanonicalObjectSchema; + export import CanonicalPropertiesTypes = ns.CanonicalPropertiesTypes; + export import CanonicalPropertySchema = ns.CanonicalPropertySchema; + export import ClientResetAfterCallback = ns.ClientResetAfterCallback; + export import ClientResetBeforeCallback = ns.ClientResetBeforeCallback; + export import ClientResetConfig = ns.ClientResetConfig; + export import ClientResetDiscardUnsyncedChangesConfiguration = ns.ClientResetDiscardUnsyncedChangesConfiguration; + export import ClientResetFallbackCallback = ns.ClientResetFallbackCallback; + export import ClientResetManualConfiguration = ns.ClientResetManualConfiguration; + export import ClientResetMode = ns.ClientResetMode; + export import ClientResetRecoverOrDiscardUnsyncedChangesConfiguration = ns.ClientResetRecoverOrDiscardUnsyncedChangesConfiguration; + export import ClientResetRecoverUnsyncedChangesConfiguration = ns.ClientResetRecoverUnsyncedChangesConfiguration; + export import Collection = ns.Collection; + export import CollectionChangeCallback = ns.CollectionChangeCallback; + export import CollectionChangeSet = ns.CollectionChangeSet; + export import CollectionPropertyTypeName = ns.CollectionPropertyTypeName; + export import CompensatingWriteError = ns.CompensatingWriteError; + export import CompensatingWriteInfo = ns.CompensatingWriteInfo; + export import Configuration = ns.Configuration; + export import ConfigurationWithoutSync = ns.ConfigurationWithoutSync; + export import ConfigurationWithSync = ns.ConfigurationWithSync; + export import ConnectionNotificationCallback = ns.ConnectionNotificationCallback; + export import ConnectionState = ns.ConnectionState; + export import Counter = ns.Counter; + export import Credentials = ns.Credentials; + export import DefaultFunctionsFactory = ns.DefaultFunctionsFactory; + export import DefaultUserProfileData = ns.DefaultUserProfileData; + export import Dictionary = ns.Dictionary; + export import DictionaryChangeCallback = ns.DictionaryChangeCallback; + export import DictionaryChangeSet = ns.DictionaryChangeSet; + export import ErrorCallback = ns.ErrorCallback; + export import EstimateProgressNotificationCallback = ns.EstimateProgressNotificationCallback; + export import FlexibleSyncConfiguration = ns.FlexibleSyncConfiguration; + export import GeoBox = ns.GeoBox; + export import GeoCircle = ns.GeoCircle; + export import GeoPoint = ns.GeoPoint; + export import GeoPolygon = ns.GeoPolygon; + export import GeoPosition = ns.GeoPosition; + export import IndexDecorator = ns.IndexDecorator; + export import IndexedType = ns.IndexedType; + export import InitialSubscriptions = ns.InitialSubscriptions; + export import List = ns.List; + export import LocalAppConfiguration = ns.LocalAppConfiguration; + export import LogCategory = ns.LogCategory; + export import LogEntry = ns.LogEntry; + export import Logger = ns.Logger; + export import LoggerCallback = ns.LoggerCallback; + export import LoggerCallback1 = ns.LoggerCallback1; + export import LoggerCallback2 = ns.LoggerCallback2; + export import MapToDecorator = ns.MapToDecorator; + export import Metadata = ns.Metadata; + export import MetadataMode = ns.MetadataMode; + export import MigrationCallback = ns.MigrationCallback; + export import MigrationOptions = ns.MigrationOptions; + export import Mixed = ns.Types.Mixed; + export import MongoDB = ns.MongoDB; + export import MongoDBService = ns.MongoDBService; + export import NumericLogLevel = ns.NumericLogLevel; + export import ObjectChangeCallback = ns.ObjectChangeCallback; + export import ObjectChangeSet = ns.ObjectChangeSet; + export import ObjectSchema = ns.ObjectSchema; + export import ObjectType = ns.ObjectType; + export import OpenRealmBehaviorConfiguration = ns.OpenRealmBehaviorConfiguration; + export import OpenRealmBehaviorType = ns.OpenRealmBehaviorType; + export import OpenRealmTimeOutBehavior = ns.OpenRealmTimeOutBehavior; + export import OrderedCollection = ns.OrderedCollection; + export import PartitionSyncConfiguration = ns.PartitionSyncConfiguration; + export import PresentationPropertyTypeName = ns.PresentationPropertyTypeName; + export import PrimaryKey = ns.PrimaryKey; + export import PrimitivePropertyTypeName = ns.PrimitivePropertyTypeName; + export import ProgressDirection = ns.ProgressDirection; + export import ProgressMode = ns.ProgressMode; + export import ProgressNotificationCallback = ns.ProgressNotificationCallback; + export import ProgressRealmPromise = ns.ProgressRealmPromise; + export import PropertiesTypes = ns.PropertiesTypes; + export import PropertySchema = ns.PropertySchema; + export import PropertySchemaCommon = ns.PropertySchemaCommon; + export import PropertySchemaParseError = ns.PropertySchemaParseError; + export import PropertySchemaShorthand = ns.PropertySchemaShorthand; + export import PropertySchemaStrict = ns.PropertySchemaStrict; + export import PropertyTypeName = ns.PropertyTypeName; + export import ProviderType = ns.ProviderType; + export import ProxyType = ns.ProxyType; + export import RealmEvent = ns.RealmEvent; + export import RealmEventName = ns.RealmEventName; + export import RealmListenerCallback = ns.RealmListenerCallback; + export import RealmObjectConstructor = ns.RealmObjectConstructor; + export import RelationshipPropertyTypeName = ns.RelationshipPropertyTypeName; + export import Results = ns.Results; + export import SchemaParseError = ns.SchemaParseError; + export import SecretApiKey = ns.SecretApiKey; + export import SessionState = ns.SessionState; + export import SessionStopPolicy = ns.SessionStopPolicy; + export import Set = ns.RealmSet; + export import ShorthandPrimitivePropertyTypeName = ns.ShorthandPrimitivePropertyTypeName; + export import SortDescriptor = ns.SortDescriptor; + export import SSLConfiguration = ns.SSLConfiguration; + export import SSLVerifyCallback = ns.SSLVerifyCallback; + export import SSLVerifyObject = ns.SSLVerifyObject; + export import SubscriptionSetState = ns.SubscriptionSetState; + export import SyncConfiguration = ns.SyncConfiguration; + export import SyncError = ns.SyncError; + export import SyncProxyConfig = ns.SyncProxyConfig; + export import TypeAssertionError = ns.TypeAssertionError; + export import Unmanaged = ns.Unmanaged; + export import UpdateMode = ns.UpdateMode; + export import User = ns.User; + export import UserChangeCallback = ns.UserChangeCallback; + export import UserIdentity = ns.UserIdentity; + export import UserState = ns.UserState; + export import UserTypeName = ns.UserTypeName; + export import WaitForSync = ns.WaitForSync; + export import WatchOptionsFilter = ns.WatchOptionsFilter; + export import WatchOptionsIds = ns.WatchOptionsIds; // Deprecated exports below - /** @deprecated Will be removed in v13.0.0. Please use {@link internal.AppServicesFunction | AppServicesFunction} */ - export import RealmFunction = internal.AppServicesFunction; - /** @deprecated Will be removed in v13.0.0. Please use {@link internal.CanonicalPropertySchema | CanonicalPropertySchema} */ - export import CanonicalObjectSchemaProperty = internal.CanonicalPropertySchema; - /** @deprecated Will be removed in v13.0.0. Please use {@link internal.ClientResetRecoverUnsyncedChangesConfiguration | ClientResetRecoverUnsyncedChangesConfiguration} */ - export import ClientResetRecoveryConfiguration = internal.ClientResetRecoverUnsyncedChangesConfiguration; - /** @deprecated Will be removed in v13.0.0. Please use {@link internal.PropertySchema | PropertySchema} */ - export import ObjectSchemaProperty = internal.PropertySchema; - /** @deprecated Will be removed in v13.0.0. Please use {@link internal.RealmObjectConstructor | RealmObjectConstructor} */ - export import ObjectClass = internal.RealmObjectConstructor; - /** @deprecated Will be removed in a future major version. Please use {@link internal.EstimateProgressNotificationCallback | EstimateProgressNotificationCallback} */ - export import PartitionBasedSyncProgressNotificationCallback = internal.PartitionBasedSyncProgressNotificationCallback; - /** @deprecated Will be removed in v13.0.0. Please use {@link internal.PropertyTypeName | PropertyTypeName} */ - export import PropertyType = internal.PropertyTypeName; - /** @deprecated Use another {@link internal.ClientResetMode | ClientResetMode} than {@link internal.ClientResetMode.Manual | ClientResetMode.Manual}. */ - export import ClientResetError = internal.ClientResetError; + /** @deprecated Will be removed in v13.0.0. Please use {@link ns.AppServicesFunction | AppServicesFunction} */ + export import RealmFunction = ns.AppServicesFunction; + /** @deprecated Will be removed in v13.0.0. Please use {@link ns.CanonicalPropertySchema | CanonicalPropertySchema} */ + export import CanonicalObjectSchemaProperty = ns.CanonicalPropertySchema; + /** @deprecated Will be removed in v13.0.0. Please use {@link ns.ClientResetRecoverUnsyncedChangesConfiguration | ClientResetRecoverUnsyncedChangesConfiguration} */ + export import ClientResetRecoveryConfiguration = ns.ClientResetRecoverUnsyncedChangesConfiguration; + /** @deprecated Will be removed in v13.0.0. Please use {@link ns.PropertySchema | PropertySchema} */ + export import ObjectSchemaProperty = ns.PropertySchema; + /** @deprecated Will be removed in v13.0.0. Please use {@link ns.RealmObjectConstructor | RealmObjectConstructor} */ + export import ObjectClass = ns.RealmObjectConstructor; + /** @deprecated Will be removed in a future major version. Please use {@link ns.EstimateProgressNotificationCallback | EstimateProgressNotificationCallback} */ + export import PartitionBasedSyncProgressNotificationCallback = ns.PartitionBasedSyncProgressNotificationCallback; + /** @deprecated Will be removed in v13.0.0. Please use {@link ns.PropertyTypeName | PropertyTypeName} */ + export import PropertyType = ns.PropertyTypeName; + /** @deprecated Use another {@link ns.ClientResetMode | ClientResetMode} than {@link ns.ClientResetMode.Manual | ClientResetMode.Manual}. */ + export import ClientResetError = ns.ClientResetError; /** @deprecated See https://www.mongodb.com/docs/atlas/app-services/reference/push-notifications/ */ - export import PushClient = internal.PushClient; + export import PushClient = ns.PushClient; } // Set default logger and log level. diff --git a/packages/realm/src/RealmListeners.ts b/packages/realm/src/RealmListeners.ts index d549721147..0a3bfe40b8 100644 --- a/packages/realm/src/RealmListeners.ts +++ b/packages/realm/src/RealmListeners.ts @@ -16,7 +16,8 @@ // //////////////////////////////////////////////////////////////////////////// -import { CanonicalObjectSchema, Realm } from "./internal"; +import type { Realm } from "./Realm"; +import type { CanonicalObjectSchema } from "./schema"; export enum RealmEvent { Change = "change", diff --git a/packages/realm/src/Results.ts b/packages/realm/src/Results.ts index 41e3560247..c9228b8f4a 100644 --- a/packages/realm/src/Results.ts +++ b/packages/realm/src/Results.ts @@ -16,24 +16,18 @@ // //////////////////////////////////////////////////////////////////////////// -import { - COLLECTION_ACCESSOR as ACCESSOR, - Dictionary, - IllegalConstructorError, - List, - OrderedCollection, - Realm, - SubscriptionOptions, - TimeoutPromise, - TypeHelpers, - Unmanaged, - WaitForSync, - assert, - binding, - createDefaultGetter, - createDictionaryAccessor, - createListAccessor, -} from "./internal"; +import { binding } from "../binding"; +import { assert } from "./assert"; +import { IllegalConstructorError } from "./errors"; +import { injectIndirect } from "./indirect"; +import { COLLECTION_ACCESSOR as ACCESSOR } from "./Collection"; +import { OrderedCollection } from "./OrderedCollection"; +import type { Realm } from "./Realm"; +import { type SubscriptionOptions, WaitForSync } from "./app-services/MutableSubscriptionSet"; +import { TimeoutPromise } from "./TimeoutPromise"; +import type { TypeHelpers } from "./TypeHelpers"; +import type { Unmanaged } from "./Unmanaged"; +import type { ResultsAccessor } from "./collection-accessors/Results"; /** * Instances of this class are typically **live** collections returned by @@ -196,58 +190,7 @@ export class Results extends OrderedCollection< } } -/** - * Accessor for getting items from the binding collection. - * @internal - */ -export type ResultsAccessor = { - get: (results: binding.Results, index: number) => T; -}; - -type ResultsAccessorFactoryOptions = { - realm: Realm; - typeHelpers: TypeHelpers; - itemType: binding.PropertyType; -}; - -/** @internal */ -export function createResultsAccessor(options: ResultsAccessorFactoryOptions): ResultsAccessor { - return options.itemType === binding.PropertyType.Mixed - ? createResultsAccessorForMixed(options) - : createResultsAccessorForKnownType(options); -} - -function createResultsAccessorForMixed({ - realm, - typeHelpers, -}: Omit, "itemType">): ResultsAccessor { - return { - get(results, index) { - const value = results.getAny(index); - switch (value) { - case binding.ListSentinel: { - const accessor = createListAccessor({ realm, typeHelpers, itemType: binding.PropertyType.Mixed }); - return new List(realm, results.getList(index), accessor, typeHelpers) as T; - } - case binding.DictionarySentinel: { - const accessor = createDictionaryAccessor({ realm, typeHelpers, itemType: binding.PropertyType.Mixed }); - return new Dictionary(realm, results.getDictionary(index), accessor, typeHelpers) as T; - } - default: - return typeHelpers.fromBinding(value); - } - }, - }; -} - -function createResultsAccessorForKnownType({ - typeHelpers, - itemType, -}: Omit, "realm">): ResultsAccessor { - return { - get: createDefaultGetter({ fromBinding: typeHelpers.fromBinding, itemType }), - }; -} - /* eslint-disable-next-line @typescript-eslint/no-explicit-any -- Useful for APIs taking any `Results` */ export type AnyResults = Results; + +injectIndirect("Results", Results); diff --git a/packages/realm/src/Set.ts b/packages/realm/src/Set.ts index 237dc3a51e..46ec5f3e3b 100644 --- a/packages/realm/src/Set.ts +++ b/packages/realm/src/Set.ts @@ -16,17 +16,15 @@ // //////////////////////////////////////////////////////////////////////////// -import { - COLLECTION_ACCESSOR as ACCESSOR, - IllegalConstructorError, - OrderedCollection, - Realm, - COLLECTION_TYPE_HELPERS as TYPE_HELPERS, - TypeHelpers, - assert, - binding, - createDefaultGetter, -} from "./internal"; +import { binding } from "../binding"; +import { assert } from "./assert"; +import { IllegalConstructorError } from "./errors"; +import { injectIndirect } from "./indirect"; +import { COLLECTION_ACCESSOR as ACCESSOR, COLLECTION_TYPE_HELPERS as TYPE_HELPERS } from "./Collection"; +import { OrderedCollection } from "./OrderedCollection"; +import type { Realm } from "./Realm"; +import type { TypeHelpers } from "./TypeHelpers"; +import type { SetAccessor } from "./collection-accessors/Set"; /** * Instances of this class will be returned when accessing object properties whose type is `"Set"` @@ -149,84 +147,7 @@ export class RealmSet extends OrderedCollection< } } -/** - * Accessor for getting and setting items in the binding collection. - * @internal - */ -export type SetAccessor = { - get: (set: binding.Set, index: number) => T; - set: (set: binding.Set, index: number, value: T) => void; - insert: (set: binding.Set, value: T) => void; -}; - -type SetAccessorFactoryOptions = { - realm: Realm; - typeHelpers: TypeHelpers; - itemType: binding.PropertyType; -}; - -/** @internal */ -export function createSetAccessor(options: SetAccessorFactoryOptions): SetAccessor { - return options.itemType === binding.PropertyType.Mixed - ? createSetAccessorForMixed(options) - : createSetAccessorForKnownType(options); -} - -function createSetAccessorForMixed({ - realm, - typeHelpers, -}: Omit, "itemType">): SetAccessor { - const { fromBinding, toBinding } = typeHelpers; - return { - get(set, index) { - // Core will not return collections within a Set. - return fromBinding(set.getAny(index)); - }, - // Directly setting by "index" to a Set is a no-op. - set: () => {}, - insert(set, value) { - assert.inTransaction(realm); - - try { - set.insertAny(toBinding(value)); - } catch (err) { - // Optimize for the valid cases by not guarding for the unsupported nested collections upfront. - throw transformError(err); - } - }, - }; -} - -function createSetAccessorForKnownType({ - realm, - typeHelpers, - itemType, -}: SetAccessorFactoryOptions): SetAccessor { - const { fromBinding, toBinding } = typeHelpers; - return { - get: createDefaultGetter({ fromBinding, itemType }), - // Directly setting by "index" to a Set is a no-op. - set: () => {}, - insert(set, value) { - assert.inTransaction(realm); - - try { - set.insertAny(toBinding(value)); - } catch (err) { - // Optimize for the valid cases by not guarding for the unsupported nested collections upfront. - throw transformError(err); - } - }, - }; -} +/* eslint-disable-next-line @typescript-eslint/no-explicit-any -- We define these once to avoid using "any" through the code */ +export type AnySet = RealmSet; -function transformError(err: unknown) { - const message = err instanceof Error ? err.message : ""; - if (message?.includes("'Array' to a Mixed") || message?.includes("'List' to a Mixed")) { - return new Error("Lists within a Set are not supported."); - } - if (message?.includes("'Object' to a Mixed") || message?.includes("'Dictionary' to a Mixed")) { - return new Error("Dictionaries within a Set are not supported."); - } - return err; -} +injectIndirect("Set", RealmSet); diff --git a/packages/realm/src/TypeHelpers.ts b/packages/realm/src/TypeHelpers.ts index d52ddb2e31..ef5dc64a78 100644 --- a/packages/realm/src/TypeHelpers.ts +++ b/packages/realm/src/TypeHelpers.ts @@ -16,7 +16,8 @@ // //////////////////////////////////////////////////////////////////////////// -import { assert, binding } from "./internal"; +import { binding } from "../binding"; +import { assert } from "./assert"; import { createIntTypeHelpers } from "./type-helpers/Int"; import { createBoolTypeHelpers } from "./type-helpers/Bool"; @@ -33,8 +34,12 @@ import { createDecimalTypeHelpers } from "./type-helpers/Decimal"; import { createUuidTypeHelpers } from "./type-helpers/Uuid"; import { createArrayTypeHelpers } from "./type-helpers/Array"; +/** @internal */ import type { TypeHelpers, TypeOptions } from "./type-helpers/types"; +/** @internal */ +export type { TypeHelpers, TypeOptions }; + function createUnsupportedTypeHelpers(): TypeHelpers { return { fromBinding() { diff --git a/packages/realm/src/Types.ts b/packages/realm/src/Types.ts index a7d278e275..c845632284 100644 --- a/packages/realm/src/Types.ts +++ b/packages/realm/src/Types.ts @@ -16,7 +16,12 @@ // //////////////////////////////////////////////////////////////////////////// -import * as internal from "./internal"; +import { BSON } from "./bson"; +import * as CounterNS from "./Counter"; +import * as ListNS from "./List"; +import * as SetNS from "./Set"; +import * as DictionaryNS from "./Dictionary"; +import * as ResultsNS from "./Results"; const GlobalDate = Date; type GlobalDate = Date; @@ -29,10 +34,10 @@ export namespace Types { export type Float = number; export type Double = number; - export import Decimal128 = internal.BSON.Decimal128; - export import ObjectId = internal.BSON.ObjectId; - export import UUID = internal.BSON.UUID; - export import Counter = internal.Counter; + export import Decimal128 = BSON.Decimal128; + export import ObjectId = BSON.ObjectId; + export import UUID = BSON.UUID; + export import Counter = CounterNS.Counter; export type Date = GlobalDate; export const Date = GlobalDate; @@ -40,12 +45,12 @@ export namespace Types { export type Data = ArrayBuffer; export const Data = ArrayBuffer; - export import List = internal.List; - export import Set = internal.RealmSet; - export import Dictionary = internal.Dictionary; + export import List = ListNS.List; + export import Set = SetNS.RealmSet; + export import Dictionary = DictionaryNS.Dictionary; export type Mixed = unknown; /* eslint-disable-next-line @typescript-eslint/no-unused-vars -- We don't use the `LinkingPropertyName` at runtime */ - export type LinkingObjects = internal.Results; - export const LinkingObjects = internal.Results; + export type LinkingObjects = ResultsNS.Results; + export const LinkingObjects = ResultsNS.Results; } diff --git a/packages/realm/src/Unmanaged.ts b/packages/realm/src/Unmanaged.ts index 3d01ce22e1..cfc177f06b 100644 --- a/packages/realm/src/Unmanaged.ts +++ b/packages/realm/src/Unmanaged.ts @@ -16,16 +16,13 @@ // //////////////////////////////////////////////////////////////////////////// -import type { AnyRealmObject, Collection, Counter, Dictionary, List, Realm, RealmSet } from "./internal"; - -/* eslint-disable-next-line @typescript-eslint/no-explicit-any -- We define these once to avoid using "any" through the code */ -export type AnyCollection = Collection; -/* eslint-disable-next-line @typescript-eslint/no-explicit-any -- We define these once to avoid using "any" through the code */ -export type AnyDictionary = Dictionary; -/* eslint-disable-next-line @typescript-eslint/no-explicit-any -- We define these once to avoid using "any" through the code */ -export type AnyList = List; -/* eslint-disable-next-line @typescript-eslint/no-explicit-any -- We define these once to avoid using "any" through the code */ -export type AnySet = RealmSet; +import type { AnyRealmObject } from "./Object"; +import type { AnyCollection, Collection } from "./Collection"; +import type { Counter } from "./Counter"; +import type { AnyDictionary, Dictionary } from "./Dictionary"; +import type { AnyList, List } from "./List"; +import type { Realm } from "./Realm"; +import type { AnySet, RealmSet } from "./Set"; type ExtractPropertyNamesOfType = { [K in keyof T]: T[K] extends PropType ? K : never; diff --git a/packages/realm/src/app-services/ApiKeyAuth.ts b/packages/realm/src/app-services/ApiKeyAuth.ts index 6ce86125ec..d0acc6e381 100644 --- a/packages/realm/src/app-services/ApiKeyAuth.ts +++ b/packages/realm/src/app-services/ApiKeyAuth.ts @@ -16,7 +16,9 @@ // //////////////////////////////////////////////////////////////////////////// -import { BSON, assert, binding } from "../internal"; +import type { binding } from "../../binding"; +import { BSON } from "../bson"; +import { assert } from "../assert"; /** * The representation of an API-key stored in the service. diff --git a/packages/realm/src/app-services/App.ts b/packages/realm/src/app-services/App.ts index b835d38612..87a1c58135 100644 --- a/packages/realm/src/app-services/App.ts +++ b/packages/realm/src/app-services/App.ts @@ -17,21 +17,19 @@ //////////////////////////////////////////////////////////////////////////// import type { AnyFetch } from "@realm/fetch"; -import { - AnyUser, - BaseConfiguration, - Credentials, - DefaultFunctionsFactory, - DefaultObject, - EmailPasswordAuth, - Listeners, - User, - assert, - binding, - createNetworkTransport, - deviceInfo, - fs, -} from "../internal"; + +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { injectIndirect } from "../indirect"; +import type { BaseConfiguration } from "../Configuration"; +import type { DefaultObject } from "../schema"; +import { Listeners } from "../Listeners"; +import { deviceInfo, fs } from "../platform"; +import { type AnyUser, User } from "./User"; +import type { Credentials } from "./Credentials"; +import type { DefaultFunctionsFactory } from "./FunctionsFactory"; +import { EmailPasswordAuth } from "./EmailPasswordAuth"; +import { createNetworkTransport } from "./NetworkTransport"; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type AnyApp = App; @@ -410,7 +408,10 @@ export class App< } } -import * as internal from "../internal"; +injectIndirect("App", App); + +import type * as CredentialsNS from "./Credentials"; +import { Sync as SyncNS } from "./Sync"; // eslint-disable-next-line @typescript-eslint/no-namespace export namespace App { @@ -418,6 +419,6 @@ export namespace App { * All credentials available for authentication. * @see https://www.mongodb.com/docs/atlas/app-services/authentication/ */ - export type Credentials = internal.Credentials; - export import Sync = internal.Sync; + export type Credentials = CredentialsNS.Credentials; + export import Sync = SyncNS; } diff --git a/packages/realm/src/app-services/Auth.ts b/packages/realm/src/app-services/Auth.ts index c540791f5b..f284d0c39e 100644 --- a/packages/realm/src/app-services/Auth.ts +++ b/packages/realm/src/app-services/Auth.ts @@ -16,11 +16,12 @@ // //////////////////////////////////////////////////////////////////////////// -import * as internal from "../internal"; +import * as EmailPasswordAuthNS from "./EmailPasswordAuth"; +import * as ApiKeyAuthNS from "./ApiKeyAuth"; // eslint-disable-next-line @typescript-eslint/no-namespace export namespace Auth { - export import EmailPasswordAuth = internal.EmailPasswordAuth; - export type ApiKey = internal.ApiKey; - export import ApiKeyAuth = internal.ApiKeyAuth; + export import EmailPasswordAuth = EmailPasswordAuthNS.EmailPasswordAuth; + export type ApiKey = ApiKeyAuthNS.ApiKey; + export import ApiKeyAuth = ApiKeyAuthNS.ApiKeyAuth; } diff --git a/packages/realm/src/app-services/BaseSubscriptionSet.ts b/packages/realm/src/app-services/BaseSubscriptionSet.ts index c7c1607863..db1e778351 100644 --- a/packages/realm/src/app-services/BaseSubscriptionSet.ts +++ b/packages/realm/src/app-services/BaseSubscriptionSet.ts @@ -16,17 +16,16 @@ // //////////////////////////////////////////////////////////////////////////// -import { - AnyResults, - MutableSubscriptionSet, - Realm, - RealmObject, - Results, - Subscription, - SubscriptionSet, - assert, - binding, -} from "../internal"; +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { indirect } from "../indirect"; +import type { Realm } from "../Realm"; +import type { Results } from "../Results"; +import { type AnyResults } from "../Results"; +import type { RealmObject } from "../Object"; +import type { MutableSubscriptionSet } from "./MutableSubscriptionSet"; +import { Subscription } from "./Subscription"; +import type { SubscriptionSet } from "./SubscriptionSet"; /** * Enum representing the state of a {@link SubscriptionSet}. @@ -218,7 +217,7 @@ export abstract class BaseSubscriptionSet { * @returns The subscription with the specified query, or `null` if the subscription is not found. */ findByQuery(query: Results>): Subscription | null { - assert.instanceOf(query, Results, "query"); + assert.instanceOf(query, indirect.Results, "query"); const subscription = this.internal.findByQuery(query.internal.query); return subscription ? (new Subscription(subscription) as Subscription) : null; // TODO: Remove the type assertion into Subscription diff --git a/packages/realm/src/app-services/Credentials.ts b/packages/realm/src/app-services/Credentials.ts index 221b8271bb..49450be34b 100644 --- a/packages/realm/src/app-services/Credentials.ts +++ b/packages/realm/src/app-services/Credentials.ts @@ -16,7 +16,9 @@ // //////////////////////////////////////////////////////////////////////////// -import { App, assert, binding } from "../internal"; +import type { App } from "./App"; +import { binding } from "../../binding"; +import { assert } from "../assert"; /** * Types of an authentication provider. diff --git a/packages/realm/src/app-services/EmailPasswordAuth.ts b/packages/realm/src/app-services/EmailPasswordAuth.ts index 4076d743d5..fd8405a411 100644 --- a/packages/realm/src/app-services/EmailPasswordAuth.ts +++ b/packages/realm/src/app-services/EmailPasswordAuth.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import { binding } from "../internal"; +import type { binding } from "../../binding"; /** * Authentication provider where users identify using email and password. diff --git a/packages/realm/src/app-services/FunctionsFactory.ts b/packages/realm/src/app-services/FunctionsFactory.ts index ee089269fe..1b7dc2940a 100644 --- a/packages/realm/src/app-services/FunctionsFactory.ts +++ b/packages/realm/src/app-services/FunctionsFactory.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import { User } from "../internal"; +import type { User } from "./User"; /** * A function which executes on the Atlas App Services server. diff --git a/packages/realm/src/app-services/MongoDB.ts b/packages/realm/src/app-services/MongoDB.ts index 9e3916db05..9b846121bf 100644 --- a/packages/realm/src/app-services/MongoDB.ts +++ b/packages/realm/src/app-services/MongoDB.ts @@ -16,38 +16,38 @@ // //////////////////////////////////////////////////////////////////////////// -import * as internal from "../internal"; +import * as ns from "./MongoDBCollection"; // eslint-disable-next-line @typescript-eslint/no-namespace export namespace MongoDB { - export import AggregatePipelineStage = internal.AggregatePipelineStage; - export import BaseChangeEvent = internal.BaseChangeEvent; - export import ChangeEvent = internal.ChangeEvent; - export import ChangeEventId = internal.ChangeEventId; - export import CountOptions = internal.CountOptions; - export import DeleteEvent = internal.DeleteEvent; - export import DeleteResult = internal.DeleteResult; - export import Document = internal.Document; - export import DocumentKey = internal.DocumentKey; - export import DocumentNamespace = internal.DocumentNamespace; - export import DropDatabaseEvent = internal.DropDatabaseEvent; - export import DropEvent = internal.DropEvent; - export import Filter = internal.Filter; - export import FindOneAndModifyOptions = internal.FindOneAndModifyOptions; - export import FindOneOptions = internal.FindOneOptions; - export import FindOptions = internal.FindOptions; - export import InsertEvent = internal.InsertEvent; - export import InsertManyResult = internal.InsertManyResult; - export import InsertOneResult = internal.InsertOneResult; - export import InvalidateEvent = internal.InvalidateEvent; - export import MongoDBCollection = internal.MongoDBCollection; - export import NewDocument = internal.NewDocument; - export import OperationType = internal.OperationType; - export import RenameEvent = internal.RenameEvent; - export import ReplaceEvent = internal.ReplaceEvent; - export import Update = internal.Update; - export import UpdateDescription = internal.UpdateDescription; - export import UpdateEvent = internal.UpdateEvent; - export import UpdateOptions = internal.UpdateOptions; - export import UpdateResult = internal.UpdateResult; + export import AggregatePipelineStage = ns.AggregatePipelineStage; + export import BaseChangeEvent = ns.BaseChangeEvent; + export import ChangeEvent = ns.ChangeEvent; + export import ChangeEventId = ns.ChangeEventId; + export import CountOptions = ns.CountOptions; + export import DeleteEvent = ns.DeleteEvent; + export import DeleteResult = ns.DeleteResult; + export import Document = ns.Document; + export import DocumentKey = ns.DocumentKey; + export import DocumentNamespace = ns.DocumentNamespace; + export import DropDatabaseEvent = ns.DropDatabaseEvent; + export import DropEvent = ns.DropEvent; + export import Filter = ns.Filter; + export import FindOneAndModifyOptions = ns.FindOneAndModifyOptions; + export import FindOneOptions = ns.FindOneOptions; + export import FindOptions = ns.FindOptions; + export import InsertEvent = ns.InsertEvent; + export import InsertManyResult = ns.InsertManyResult; + export import InsertOneResult = ns.InsertOneResult; + export import InvalidateEvent = ns.InvalidateEvent; + export import MongoDBCollection = ns.MongoDBCollection; + export import NewDocument = ns.NewDocument; + export import OperationType = ns.OperationType; + export import RenameEvent = ns.RenameEvent; + export import ReplaceEvent = ns.ReplaceEvent; + export import Update = ns.Update; + export import UpdateDescription = ns.UpdateDescription; + export import UpdateEvent = ns.UpdateEvent; + export import UpdateOptions = ns.UpdateOptions; + export import UpdateResult = ns.UpdateResult; } diff --git a/packages/realm/src/app-services/MongoDBCollection.ts b/packages/realm/src/app-services/MongoDBCollection.ts index 9f8b86ec50..a3f2ee5245 100644 --- a/packages/realm/src/app-services/MongoDBCollection.ts +++ b/packages/realm/src/app-services/MongoDBCollection.ts @@ -16,9 +16,12 @@ // //////////////////////////////////////////////////////////////////////////// -import { Long, Timestamp } from "bson"; +import type { Long, Timestamp } from "bson"; -import { DefaultFunctionsFactory, User, binding, createFactory, toArrayBuffer } from "../internal"; +import { binding } from "../../binding"; +import { toArrayBuffer } from "../type-helpers/array-buffer"; +import type { User } from "./User"; +import { type DefaultFunctionsFactory, createFactory } from "./FunctionsFactory"; /** * A remote MongoDB service enabling access to an Atlas cluster. diff --git a/packages/realm/src/app-services/MutableSubscriptionSet.ts b/packages/realm/src/app-services/MutableSubscriptionSet.ts index 7bdf1cce10..741fb24158 100644 --- a/packages/realm/src/app-services/MutableSubscriptionSet.ts +++ b/packages/realm/src/app-services/MutableSubscriptionSet.ts @@ -16,16 +16,14 @@ // //////////////////////////////////////////////////////////////////////////// -import { - AnyResults, - BaseSubscriptionSet, - Realm, - Results, - Subscription, - SubscriptionSet, - assert, - binding, -} from "../internal"; +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { indirect } from "../indirect"; +import type { Realm } from "../Realm"; +import type { AnyResults, Results } from "../Results"; +import { BaseSubscriptionSet } from "./BaseSubscriptionSet"; +import { Subscription } from "./Subscription"; +import type { SubscriptionSet } from "./SubscriptionSet"; /** * Behavior when waiting for subscribed objects to be synchronized/downloaded. @@ -108,7 +106,7 @@ export class MutableSubscriptionSet extends BaseSubscriptionSet { * @returns A `Subscription` instance for the new subscription. */ add(query: AnyResults, options?: SubscriptionOptions): Subscription { - assert.instanceOf(query, Results, "query"); + assert.instanceOf(query, indirect.Results, "query"); if (options) { validateSubscriptionOptions(options); } @@ -147,7 +145,7 @@ export class MutableSubscriptionSet extends BaseSubscriptionSet { * @returns `true` if the subscription was removed, `false` if it was not found. */ remove(query: AnyResults): boolean { - assert.instanceOf(query, Results, "query"); + assert.instanceOf(query, indirect.Results, "query"); return this.internal.eraseByQuery(query.internal.query); } diff --git a/packages/realm/src/app-services/NetworkTransport.ts b/packages/realm/src/app-services/NetworkTransport.ts index 60357f5dfb..4adb58eda8 100644 --- a/packages/realm/src/app-services/NetworkTransport.ts +++ b/packages/realm/src/app-services/NetworkTransport.ts @@ -16,9 +16,12 @@ // //////////////////////////////////////////////////////////////////////////// -import { binding, extendDebug, network } from "../internal"; import type { Headers } from "@realm/fetch"; +import { binding } from "../../binding"; +import { extendDebug } from "../debug"; +import { network } from "../platform"; + const debug = extendDebug("network"); function flattenHeaders(headers: Headers) { diff --git a/packages/realm/src/app-services/PushClient.ts b/packages/realm/src/app-services/PushClient.ts index 46f7a97183..aa1b7a810b 100644 --- a/packages/realm/src/app-services/PushClient.ts +++ b/packages/realm/src/app-services/PushClient.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import { binding } from "../internal"; +import type { binding } from "../../binding"; /** * Authentication provider where users identify using an API-key. * @deprecated https://www.mongodb.com/docs/atlas/app-services/reference/push-notifications/ diff --git a/packages/realm/src/app-services/Services.ts b/packages/realm/src/app-services/Services.ts index 9b226e603d..ef604db3fb 100644 --- a/packages/realm/src/app-services/Services.ts +++ b/packages/realm/src/app-services/Services.ts @@ -16,12 +16,14 @@ // //////////////////////////////////////////////////////////////////////////// -import * as internal from "../internal"; +import * as MongoDBNS from "./MongoDB"; +import * as MongoDBCollectionNS from "./MongoDBCollection"; +import type * as PushClientNS from "./PushClient"; // eslint-disable-next-line @typescript-eslint/no-namespace export namespace Services { - export import MongoDB = internal.MongoDB; - export import MongoDBDatabase = internal.MongoDBDatabase; + export import MongoDB = MongoDBNS.MongoDB; + export import MongoDBDatabase = MongoDBCollectionNS.MongoDBDatabase; /** @deprecated Please read {@link https://www.mongodb.com/docs/atlas/app-services/reference/push-notifications/} */ - export type Push = internal.PushClient; + export type Push = PushClientNS.PushClient; } diff --git a/packages/realm/src/app-services/Subscription.ts b/packages/realm/src/app-services/Subscription.ts index a2686c9d58..26bb893731 100644 --- a/packages/realm/src/app-services/Subscription.ts +++ b/packages/realm/src/app-services/Subscription.ts @@ -16,7 +16,9 @@ // //////////////////////////////////////////////////////////////////////////// -import { BSON, SubscriptionSet, binding } from "../internal"; +import type { binding } from "../../binding"; +import type { SubscriptionSet } from "./SubscriptionSet"; +import type { BSON } from "../bson"; /** * Class representing a single query subscription in a set of flexible sync diff --git a/packages/realm/src/app-services/SubscriptionSet.ts b/packages/realm/src/app-services/SubscriptionSet.ts index cdd34fcf3e..6496ced9a6 100644 --- a/packages/realm/src/app-services/SubscriptionSet.ts +++ b/packages/realm/src/app-services/SubscriptionSet.ts @@ -16,15 +16,12 @@ // //////////////////////////////////////////////////////////////////////////// -import { - BaseSubscriptionSet, - FlexibleSyncConfiguration, - MutableSubscriptionSet, - Realm, - SubscriptionSetState, - assert, - binding, -} from "../internal"; +import { binding } from "../../binding"; +import { assert } from "../assert"; +import type { Realm } from "../Realm"; +import { BaseSubscriptionSet, SubscriptionSetState } from "./BaseSubscriptionSet"; +import { MutableSubscriptionSet } from "./MutableSubscriptionSet"; +import type { FlexibleSyncConfiguration } from "./SyncConfiguration"; /** * Represents the set of all active flexible sync subscriptions for a Realm instance. diff --git a/packages/realm/src/app-services/Sync.ts b/packages/realm/src/app-services/Sync.ts index 7910f7257f..15b1088672 100644 --- a/packages/realm/src/app-services/Sync.ts +++ b/packages/realm/src/app-services/Sync.ts @@ -16,26 +16,21 @@ // //////////////////////////////////////////////////////////////////////////// +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { type LogLevel, type Logger, fromBindingLoggerLevelToNumericLogLevel, toBindingLoggerLevel } from "../Logger"; +import type { Realm } from "../Realm"; +import { SyncSession } from "./SyncSession"; +import type { App } from "./App"; +import type { User } from "./User"; import { - App, - LogLevel, - Logger, - OpenRealmBehaviorConfiguration, + type OpenRealmBehaviorConfiguration, OpenRealmBehaviorType, OpenRealmTimeOutBehavior, - PartitionValue, - Realm, - SyncSession, - User, - assert, - binding, - fromBindingLoggerLevelToNumericLogLevel, - toBindingLoggerLevel, + type PartitionValue, toBindingSyncConfig, validateSyncConfiguration, -} from "../internal"; - -import * as internal from "../internal"; +} from "./SyncConfiguration"; export class Sync { /** @deprecated Will be removed in v13.0.0. Please use {@link Realm.setLogLevel}. */ @@ -181,19 +176,28 @@ export class Sync { }; } +// import * as internal from "../internal"; +import * as SyncSessionNS from "./SyncSession"; +import * as SyncConfigurationNS from "./SyncConfiguration"; +import * as BaseSubscriptionSetNS from "./BaseSubscriptionSet"; +import * as SubscriptionSetNS from "./SubscriptionSet"; +import * as SubscriptionNS from "./Subscription"; +import * as MutableSubscriptionSetNS from "./MutableSubscriptionSet"; +import * as LogLevelNS from "../Logger"; + // eslint-disable-next-line @typescript-eslint/no-namespace export namespace Sync { - export import ConnectionState = internal.ConnectionState; - export import BaseSubscriptionSet = internal.BaseSubscriptionSet; - export import LogLevel = internal.LogLevel; - export import NumericLogLevel = internal.NumericLogLevel; - export import MutableSubscriptionSet = internal.MutableSubscriptionSet; - export import PartitionValue = internal.PartitionValue; - export import SubscriptionOptions = internal.SubscriptionOptions; - export import SubscriptionSet = internal.SubscriptionSet; - export import SubscriptionSetState = internal.SubscriptionSetState; - /** @deprecated Please use {@link internal.SubscriptionSetState | SubscriptionSetState} */ - export import SubscriptionsState = internal.SubscriptionSetState; - export import Subscription = internal.Subscription; - export import Session = internal.SyncSession; + export import ConnectionState = SyncSessionNS.ConnectionState; + export import BaseSubscriptionSet = BaseSubscriptionSetNS.BaseSubscriptionSet; + export import LogLevel = LogLevelNS.LogLevel; + export import NumericLogLevel = LogLevelNS.NumericLogLevel; + export import MutableSubscriptionSet = MutableSubscriptionSetNS.MutableSubscriptionSet; + export import PartitionValue = SyncConfigurationNS.PartitionValue; + export import SubscriptionOptions = MutableSubscriptionSetNS.SubscriptionOptions; + export import SubscriptionSet = SubscriptionSetNS.SubscriptionSet; + export import SubscriptionSetState = BaseSubscriptionSetNS.SubscriptionSetState; + /** @deprecated Please use {@link BaseSubscriptionSetNS.SubscriptionSetState | SubscriptionSetState} */ + export import SubscriptionsState = BaseSubscriptionSetNS.SubscriptionSetState; + export import Subscription = SubscriptionNS.Subscription; + export import Session = SyncSessionNS.SyncSession; } diff --git a/packages/realm/src/app-services/SyncConfiguration.ts b/packages/realm/src/app-services/SyncConfiguration.ts index cae24b79d3..3eaac521fd 100644 --- a/packages/realm/src/app-services/SyncConfiguration.ts +++ b/packages/realm/src/app-services/SyncConfiguration.ts @@ -16,22 +16,18 @@ // //////////////////////////////////////////////////////////////////////////// -import { EJSON, ObjectId, UUID } from "bson"; - +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { BSON } from "../bson"; +import type { ClientResetError, SyncError } from "../errors"; +import { TypeAssertionError } from "../errors"; +import type { Realm } from "../Realm"; +import { syncProxyConfig } from "../platform"; +import { type AnyUser, User } from "./User"; +import type { MutableSubscriptionSet } from "./MutableSubscriptionSet"; +import type { SubscriptionSet } from "./SubscriptionSet"; import { - AnyUser, - BSON, - ClientResetError, - MutableSubscriptionSet, - Realm, - SubscriptionSet, - SyncError, - SyncSession, - TypeAssertionError, - User, - assert, - binding, - syncProxyConfig, + type SyncSession, toBindingClientResetMode, toBindingErrorHandler, toBindingErrorHandlerWithOnManual, @@ -39,7 +35,7 @@ import { toBindingNotifyAfterClientResetWithFallback, toBindingNotifyBeforeClientReset, toBindingStopPolicy, -} from "../internal"; +} from "./SyncSession"; export type PartitionValue = string | number | BSON.ObjectId | BSON.UUID | null; @@ -342,7 +338,7 @@ export function toBindingSyncConfig(config: SyncConfiguration): binding.SyncConf return { user: syncUser, - partitionValue: flexible ? undefined : EJSON.stringify(partitionValue), + partitionValue: flexible ? undefined : BSON.EJSON.stringify(partitionValue), flxSyncRequested: !!flexible, stopPolicy: _sessionStopPolicy ? toBindingStopPolicy(_sessionStopPolicy) @@ -633,7 +629,7 @@ function validatePartitionValue(value: unknown): asserts value is PartitionValue ); } else { assert( - typeof value === "string" || value instanceof ObjectId || value instanceof UUID || value === null, + typeof value === "string" || value instanceof BSON.ObjectId || value instanceof BSON.UUID || value === null, `Expected 'partitionValue' on realm sync configuration to be an integer, string, ObjectId, UUID, or null, got ${TypeAssertionError.deriveType( value, )}.`, diff --git a/packages/realm/src/app-services/SyncSession.ts b/packages/realm/src/app-services/SyncSession.ts index 198256149f..7155a6441a 100644 --- a/packages/realm/src/app-services/SyncSession.ts +++ b/packages/realm/src/app-services/SyncSession.ts @@ -18,25 +18,24 @@ import { EJSON } from "bson"; +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { ClientResetError, fromBindingSyncError } from "../errors"; +import { indirect } from "../indirect"; +import { Listeners } from "../Listeners"; +import { TimeoutPromise } from "../TimeoutPromise"; +import type { App } from "./App"; import { - App, - ClientResetAfterCallback, - ClientResetBeforeCallback, - ClientResetError, - ClientResetFallbackCallback, + type ClientResetAfterCallback, + type ClientResetBeforeCallback, + type ClientResetFallbackCallback, ClientResetMode, - ErrorCallback, - Listeners, - PartitionValue, - Realm, + type ErrorCallback, + type PartitionValue, SessionStopPolicy, - SyncConfiguration, - TimeoutPromise, - User, - assert, - binding, - fromBindingSyncError, -} from "../internal"; + type SyncConfiguration, +} from "./SyncConfiguration"; +import { User } from "./User"; /** * The progress direction to register the progress notifier for. @@ -206,7 +205,7 @@ export function toBindingErrorHandlerWithOnManual( /** @internal */ export function toBindingNotifyBeforeClientReset(onBefore: ClientResetBeforeCallback) { return (internal: binding.Realm) => { - onBefore(new Realm(null, { internal })); + onBefore(new indirect.Realm(null, { internal })); }; } @@ -214,8 +213,8 @@ export function toBindingNotifyBeforeClientReset(onBefore: ClientResetBeforeCall export function toBindingNotifyAfterClientReset(onAfter: ClientResetAfterCallback) { return (internal: binding.Realm, tsr: binding.ThreadSafeReference) => { onAfter( - new Realm(null, { internal }), - new Realm(null, { internal: binding.Helpers.consumeThreadSafeReferenceToSharedRealm(tsr) }), + new indirect.Realm(null, { internal }), + new indirect.Realm(null, { internal: binding.Helpers.consumeThreadSafeReferenceToSharedRealm(tsr) }), ); }; } @@ -228,11 +227,13 @@ export function toBindingNotifyAfterClientResetWithFallback( return (internal: binding.Realm, tsr: binding.ThreadSafeReference, didRecover: boolean) => { if (didRecover) { onAfter( - new Realm(null, { internal }), - new Realm(null, { internal: binding.Helpers.consumeThreadSafeReferenceToSharedRealm(tsr) }), + new indirect.Realm(null, { internal }), + new indirect.Realm(null, { internal: binding.Helpers.consumeThreadSafeReferenceToSharedRealm(tsr) }), ); } else { - const realm = new Realm(null, { internal: binding.Helpers.consumeThreadSafeReferenceToSharedRealm(tsr) }); + const realm = new indirect.Realm(null, { + internal: binding.Helpers.consumeThreadSafeReferenceToSharedRealm(tsr), + }); if (onFallback) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion onFallback(realm.syncSession!, realm.path); diff --git a/packages/realm/src/app-services/User.ts b/packages/realm/src/app-services/User.ts index 7eab2bed9d..90204ff8f7 100644 --- a/packages/realm/src/app-services/User.ts +++ b/packages/realm/src/app-services/User.ts @@ -16,28 +16,23 @@ // //////////////////////////////////////////////////////////////////////////// -import { - AnyApp, - ApiKeyAuth, - App, - Credentials, - DefaultFunctionsFactory, - DefaultObject, - DefaultUserProfileData, - Document, - Listeners, - MongoDBCollection, - MongoDBService, - ProviderType, - PushClient, - assert, - asyncIteratorFromResponse, - binding, - cleanArguments, - createFactory, - isProviderType, - network, -} from "../internal"; +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { indirect, injectIndirect } from "../indirect"; +import { network } from "../platform"; +import type { DefaultObject } from "../schema"; +import { Listeners } from "../Listeners"; +import { asyncIteratorFromResponse } from "../async-iterator-from-response"; +import { cleanArguments } from "./utils"; +import type { App } from "./App"; +import type { AnyApp } from "./App"; +import { ApiKeyAuth } from "./ApiKeyAuth"; +import type { ProviderType } from "./Credentials"; +import { type Credentials, isProviderType } from "./Credentials"; +import { type DefaultFunctionsFactory, createFactory } from "./FunctionsFactory"; +import type { DefaultUserProfileData } from "./UserProfile"; +import { type Document, MongoDBCollection, type MongoDBService } from "./MongoDBCollection"; +import { PushClient } from "./PushClient"; export type UserChangeCallback = () => void; @@ -113,10 +108,13 @@ export class User< >(internal: binding.User, app?: AnyApp) { // Update the static user reference to the current app if (app) { - App.setAppByUser(internal, app); + indirect.App.setAppByUser(internal, app); } // TODO: Use a WeakRef to memoize the SDK object - return new User(internal, App.getAppByUser(internal)); + return new User( + internal, + indirect.App.getAppByUser(internal), + ); } /** @internal */ @@ -159,7 +157,7 @@ export class User< * The provider type used when authenticating the user. If multiple identities exist, * the provider type for the first identity found is return. * @returns The provider type as an enumerated string. - * @deprecated Use {@link identities} instead. + * @deprecated Use {@link User.identities} instead. */ get providerType(): ProviderType { const [identity] = this.internal.identities; @@ -262,7 +260,7 @@ export class User< /** * Use this to call functions defined by the Atlas App Services application, as this user. - * @returns A {@link UserFunctionsFactoryType} that can be used to call the app's functions. + * @returns A {@link User.UserFunctionsFactoryType} that can be used to call the app's functions. */ get functions(): UserFunctionsFactoryType { return createFactory(this as User, undefined); @@ -414,3 +412,5 @@ export class User< this.listeners.removeAll(); } } + +injectIndirect("User", User); diff --git a/packages/realm/src/app-services/utils.ts b/packages/realm/src/app-services/utils.ts index f21ae6b74b..629d36e528 100644 --- a/packages/realm/src/app-services/utils.ts +++ b/packages/realm/src/app-services/utils.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import { binding } from "../internal"; +import type { binding } from "../../binding"; /** * Remove entries for undefined property values. diff --git a/packages/realm/src/assert.ts b/packages/realm/src/assert.ts index e8e705cc31..d3d7e50d2b 100644 --- a/packages/realm/src/assert.ts +++ b/packages/realm/src/assert.ts @@ -16,7 +16,10 @@ // //////////////////////////////////////////////////////////////////////////// -import { AssertionError, BSON, DefaultObject, PrimaryKey, Realm, TypeAssertionError, binding } from "./internal"; +import type { binding } from "../binding"; +import { AssertionError, TypeAssertionError } from "./errors"; +import type { DefaultObject } from "./schema"; +import type { Realm } from "./Realm"; /** * Expects the condition to be truthy @@ -138,17 +141,6 @@ assert.never = (value: never, target?: string): never => { // SDK specific -assert.primaryKey = (value: unknown, target?: string): asserts value is PrimaryKey => { - assert( - value === null || - typeof value === "number" || - typeof value === "string" || - value instanceof BSON.UUID || - value instanceof BSON.ObjectId, - () => new TypeAssertionError("a primary key", value, target), - ); -}; - assert.open = (realm: Realm) => { assert(!realm.isClosed, "Cannot access realm that has been closed."); }; diff --git a/packages/realm/src/async-iterator-from-response.ts b/packages/realm/src/async-iterator-from-response.ts index a760fc0d15..9e84d15d11 100644 --- a/packages/realm/src/async-iterator-from-response.ts +++ b/packages/realm/src/async-iterator-from-response.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import { Response } from "@realm/fetch"; +import type { Response } from "@realm/fetch"; // Falling back on a known string used in code transpiled by Babel const asyncIteratorSymbol: typeof Symbol.asyncIterator = Symbol.asyncIterator || "@@asyncIterator"; diff --git a/packages/realm/src/collection-accessors/Dictionary.ts b/packages/realm/src/collection-accessors/Dictionary.ts new file mode 100644 index 0000000000..b2fb9b02d2 --- /dev/null +++ b/packages/realm/src/collection-accessors/Dictionary.ts @@ -0,0 +1,143 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2024 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. +// +//////////////////////////////////////////////////////////////////////////// + +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { indirect } from "../indirect"; +import type { Dictionary } from "../Dictionary"; +import { createListAccessor, insertIntoListOfMixed, isJsOrRealmList } from "./List"; +import type { TypeHelpers } from "../TypeHelpers"; +import type { Realm } from "../Realm"; + +/** @internal */ +export type DictionaryAccessor = { + get: (dictionary: binding.Dictionary, key: string) => T; + set: (dictionary: binding.Dictionary, key: string, value: T) => void; +}; + +type DictionaryAccessorFactoryOptions = { + realm: Realm; + typeHelpers: TypeHelpers; + itemType: binding.PropertyType; + isEmbedded?: boolean; +}; + +/** @internal */ +export function createDictionaryAccessor(options: DictionaryAccessorFactoryOptions): DictionaryAccessor { + return options.itemType === binding.PropertyType.Mixed + ? createDictionaryAccessorForMixed(options) + : createDictionaryAccessorForKnownType(options); +} + +function createDictionaryAccessorForMixed({ + realm, + typeHelpers, +}: Pick, "realm" | "typeHelpers">): DictionaryAccessor { + const { toBinding, fromBinding } = typeHelpers; + return { + get(dictionary, key) { + const value = dictionary.tryGetAny(key); + switch (value) { + case binding.ListSentinel: { + const accessor = createListAccessor({ realm, itemType: binding.PropertyType.Mixed, typeHelpers }); + return new indirect.List(realm, dictionary.getList(key), accessor, typeHelpers) as T; + } + case binding.DictionarySentinel: { + const accessor = createDictionaryAccessor({ realm, itemType: binding.PropertyType.Mixed, typeHelpers }); + return new indirect.Dictionary(realm, dictionary.getDictionary(key), accessor, typeHelpers) as T; + } + default: + return fromBinding(value) as T; + } + }, + set(dictionary, key, value) { + assert.inTransaction(realm); + + if (isJsOrRealmList(value)) { + dictionary.insertCollection(key, binding.CollectionType.List); + insertIntoListOfMixed(value, dictionary.getList(key), toBinding); + } else if (isJsOrRealmDictionary(value)) { + dictionary.insertCollection(key, binding.CollectionType.Dictionary); + insertIntoDictionaryOfMixed(value, dictionary.getDictionary(key), toBinding); + } else { + dictionary.insertAny(key, toBinding(value)); + } + }, + }; +} + +function createDictionaryAccessorForKnownType({ + realm, + typeHelpers, + isEmbedded, +}: Omit, "itemType">): DictionaryAccessor { + const { fromBinding, toBinding } = typeHelpers; + return { + get(dictionary, key) { + return fromBinding(dictionary.tryGetAny(key)); + }, + set(dictionary, key, value) { + assert.inTransaction(realm); + + if (isEmbedded) { + toBinding(value, { createObj: () => [dictionary.insertEmbedded(key), true] }); + } else { + dictionary.insertAny(key, toBinding(value)); + } + }, + }; +} + +/** @internal */ +export function insertIntoDictionaryOfMixed( + dictionary: Dictionary | Record, + internal: binding.Dictionary, + toBinding: TypeHelpers["toBinding"], +) { + // TODO: Solve the "removeAll()" case for self-assignment (https://github.com/realm/realm-core/issues/7422). + internal.removeAll(); + + for (const key in dictionary) { + const value = dictionary[key]; + if (isJsOrRealmList(value)) { + internal.insertCollection(key, binding.CollectionType.List); + insertIntoListOfMixed(value, internal.getList(key), toBinding); + } else if (isJsOrRealmDictionary(value)) { + internal.insertCollection(key, binding.CollectionType.Dictionary); + insertIntoDictionaryOfMixed(value, internal.getDictionary(key), toBinding); + } else { + internal.insertAny(key, toBinding(value)); + } + } +} + +/** @internal */ +export function isJsOrRealmDictionary(value: unknown): value is Dictionary | Record { + return isPOJO(value) || value instanceof indirect.Dictionary; +} + +/** @internal */ +export function isPOJO(value: unknown): value is Record { + return ( + typeof value === "object" && + value !== null && + // Lastly check for the absence of a prototype as POJOs + // can still be created using `Object.create(null)`. + (value.constructor === Object || !Object.getPrototypeOf(value)) + ); +} diff --git a/packages/realm/src/collection-accessors/List.ts b/packages/realm/src/collection-accessors/List.ts new file mode 100644 index 0000000000..801e43c632 --- /dev/null +++ b/packages/realm/src/collection-accessors/List.ts @@ -0,0 +1,152 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2024 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. +// +//////////////////////////////////////////////////////////////////////////// + +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { indirect } from "../indirect"; +import { createDictionaryAccessor, insertIntoDictionaryOfMixed, isJsOrRealmDictionary } from "./Dictionary"; +import { createDefaultGetter } from "./OrderedCollection"; +import type { TypeHelpers } from "../TypeHelpers"; +import type { Realm } from "../Realm"; +import type { List } from "../List"; + +/** @internal */ +export type ListAccessor = { + get: (list: binding.List, index: number) => T; + set: (list: binding.List, index: number, value: T) => void; + insert: (list: binding.List, index: number, value: T) => void; +}; + +type ListAccessorFactoryOptions = { + realm: Realm; + typeHelpers: TypeHelpers; + itemType: binding.PropertyType; + isEmbedded?: boolean; +}; + +/** @internal */ +export function createListAccessor(options: ListAccessorFactoryOptions): ListAccessor { + return options.itemType === binding.PropertyType.Mixed + ? createListAccessorForMixed(options) + : createListAccessorForKnownType(options); +} + +function createListAccessorForMixed({ + realm, + typeHelpers, +}: Pick, "realm" | "typeHelpers">): ListAccessor { + const { toBinding } = typeHelpers; + return { + get(list, index) { + const value = list.getAny(index); + switch (value) { + case binding.ListSentinel: { + const accessor = createListAccessor({ realm, typeHelpers, itemType: binding.PropertyType.Mixed }); + return new indirect.List(realm, list.getList(index), accessor, typeHelpers) as T; + } + case binding.DictionarySentinel: { + const accessor = createDictionaryAccessor({ realm, typeHelpers, itemType: binding.PropertyType.Mixed }); + return new indirect.Dictionary(realm, list.getDictionary(index), accessor, typeHelpers) as T; + } + default: + return typeHelpers.fromBinding(value); + } + }, + set(list, index, value) { + assert.inTransaction(realm); + + if (isJsOrRealmList(value)) { + list.setCollection(index, binding.CollectionType.List); + insertIntoListOfMixed(value, list.getList(index), toBinding); + } else if (isJsOrRealmDictionary(value)) { + list.setCollection(index, binding.CollectionType.Dictionary); + insertIntoDictionaryOfMixed(value, list.getDictionary(index), toBinding); + } else { + list.setAny(index, toBinding(value)); + } + }, + insert(list, index, value) { + assert.inTransaction(realm); + + if (isJsOrRealmList(value)) { + list.insertCollection(index, binding.CollectionType.List); + insertIntoListOfMixed(value, list.getList(index), toBinding); + } else if (isJsOrRealmDictionary(value)) { + list.insertCollection(index, binding.CollectionType.Dictionary); + insertIntoDictionaryOfMixed(value, list.getDictionary(index), toBinding); + } else { + list.insertAny(index, toBinding(value)); + } + }, + }; +} + +function createListAccessorForKnownType({ + realm, + typeHelpers, + itemType, + isEmbedded, +}: Omit, "isMixed">): ListAccessor { + const { fromBinding, toBinding } = typeHelpers; + return { + get: createDefaultGetter({ fromBinding, itemType }), + set(list, index, value) { + assert.inTransaction(realm); + list.setAny( + index, + toBinding(value, isEmbedded ? { createObj: () => [list.setEmbedded(index), true] } : undefined), + ); + }, + insert(list, index, value) { + assert.inTransaction(realm); + if (isEmbedded) { + // Simply transforming to binding will insert the embedded object + toBinding(value, { createObj: () => [list.insertEmbedded(index), true] }); + } else { + list.insertAny(index, toBinding(value)); + } + }, + }; +} + +/** @internal */ +export function insertIntoListOfMixed( + list: List | unknown[], + internal: binding.List, + toBinding: TypeHelpers["toBinding"], +) { + // TODO: Solve the "removeAll()" case for self-assignment (https://github.com/realm/realm-core/issues/7422). + internal.removeAll(); + + for (const [index, item] of list.entries()) { + if (isJsOrRealmList(item)) { + internal.insertCollection(index, binding.CollectionType.List); + insertIntoListOfMixed(item, internal.getList(index), toBinding); + } else if (isJsOrRealmDictionary(item)) { + internal.insertCollection(index, binding.CollectionType.Dictionary); + insertIntoDictionaryOfMixed(item, internal.getDictionary(index), toBinding); + } else { + internal.insertAny(index, toBinding(item)); + } + } +} + +/** @internal */ +export function isJsOrRealmList(value: unknown): value is List | unknown[] { + return Array.isArray(value) || value instanceof indirect.List; +} diff --git a/packages/realm/src/collection-accessors/OrderedCollection.ts b/packages/realm/src/collection-accessors/OrderedCollection.ts new file mode 100644 index 0000000000..39f079e001 --- /dev/null +++ b/packages/realm/src/collection-accessors/OrderedCollection.ts @@ -0,0 +1,53 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2024 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. +// +//////////////////////////////////////////////////////////////////////////// + +import { binding } from "../../binding"; +import type { OrderedCollectionInternal } from "../OrderedCollection"; +import type { TypeHelpers } from "../TypeHelpers"; + +type Getter = (collection: CollectionType, index: number) => T; + +type GetterFactoryOptions = { + fromBinding: TypeHelpers["fromBinding"]; + itemType: binding.PropertyType; +}; + +/** @internal */ +export function createDefaultGetter({ + fromBinding, + itemType, +}: GetterFactoryOptions): Getter { + const isObjectItem = itemType === binding.PropertyType.Object || itemType === binding.PropertyType.LinkingObjects; + return isObjectItem ? (...args) => getObject(fromBinding, ...args) : (...args) => getKnownType(fromBinding, ...args); +} + +function getObject( + fromBinding: TypeHelpers["fromBinding"], + collection: OrderedCollectionInternal, + index: number, +): T { + return fromBinding(collection.getObj(index)); +} + +function getKnownType( + fromBinding: TypeHelpers["fromBinding"], + collection: OrderedCollectionInternal, + index: number, +): T { + return fromBinding(collection.getAny(index)); +} diff --git a/packages/realm/src/collection-accessors/Results.ts b/packages/realm/src/collection-accessors/Results.ts new file mode 100644 index 0000000000..a417cdd030 --- /dev/null +++ b/packages/realm/src/collection-accessors/Results.ts @@ -0,0 +1,74 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2024 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. +// +//////////////////////////////////////////////////////////////////////////// + +import { binding } from "../../binding"; +import { indirect } from "../indirect"; +import { createDictionaryAccessor } from "./Dictionary"; +import { createListAccessor } from "./List"; +import { createDefaultGetter } from "./OrderedCollection"; +import type { TypeHelpers } from "../TypeHelpers"; + +/** @internal */ +export type ResultsAccessor = { + get: (results: binding.Results, index: number) => T; +}; + +type ResultsAccessorFactoryOptions = { + realm: Realm; + typeHelpers: TypeHelpers; + itemType: binding.PropertyType; +}; + +/** @internal */ +export function createResultsAccessor(options: ResultsAccessorFactoryOptions): ResultsAccessor { + return options.itemType === binding.PropertyType.Mixed + ? createResultsAccessorForMixed(options) + : createResultsAccessorForKnownType(options); +} + +function createResultsAccessorForMixed({ + realm, + typeHelpers, +}: Omit, "itemType">): ResultsAccessor { + return { + get(results, index) { + const value = results.getAny(index); + switch (value) { + case binding.ListSentinel: { + const accessor = createListAccessor({ realm, typeHelpers, itemType: binding.PropertyType.Mixed }); + return new indirect.List(realm, results.getList(index), accessor, typeHelpers) as T; + } + case binding.DictionarySentinel: { + const accessor = createDictionaryAccessor({ realm, typeHelpers, itemType: binding.PropertyType.Mixed }); + return new indirect.Dictionary(realm, results.getDictionary(index), accessor, typeHelpers) as T; + } + default: + return typeHelpers.fromBinding(value); + } + }, + }; +} + +function createResultsAccessorForKnownType({ + typeHelpers, + itemType, +}: Omit, "realm">): ResultsAccessor { + return { + get: createDefaultGetter({ fromBinding: typeHelpers.fromBinding, itemType }), + }; +} diff --git a/packages/realm/src/collection-accessors/Set.ts b/packages/realm/src/collection-accessors/Set.ts new file mode 100644 index 0000000000..3dfacddef7 --- /dev/null +++ b/packages/realm/src/collection-accessors/Set.ts @@ -0,0 +1,102 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2024 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. +// +//////////////////////////////////////////////////////////////////////////// + +import { binding } from "../../binding"; +import { assert } from "../assert"; +import type { TypeHelpers } from "../TypeHelpers"; +import type { Realm } from "../Realm"; +import { createDefaultGetter } from "./OrderedCollection"; + +/** @internal */ +export type SetAccessor = { + get: (set: binding.Set, index: number) => T; + set: (set: binding.Set, index: number, value: T) => void; + insert: (set: binding.Set, value: T) => void; +}; + +type SetAccessorFactoryOptions = { + realm: Realm; + typeHelpers: TypeHelpers; + itemType: binding.PropertyType; +}; + +/** @internal */ +export function createSetAccessor(options: SetAccessorFactoryOptions): SetAccessor { + return options.itemType === binding.PropertyType.Mixed + ? createSetAccessorForMixed(options) + : createSetAccessorForKnownType(options); +} + +function createSetAccessorForMixed({ + realm, + typeHelpers, +}: Omit, "itemType">): SetAccessor { + const { fromBinding, toBinding } = typeHelpers; + return { + get(set, index) { + // Core will not return collections within a Set. + return fromBinding(set.getAny(index)); + }, + // Directly setting by "index" to a Set is a no-op. + set: () => {}, + insert(set, value) { + assert.inTransaction(realm); + + try { + set.insertAny(toBinding(value)); + } catch (err) { + // Optimize for the valid cases by not guarding for the unsupported nested collections upfront. + throw transformError(err); + } + }, + }; +} + +function createSetAccessorForKnownType({ + realm, + typeHelpers, + itemType, +}: SetAccessorFactoryOptions): SetAccessor { + const { fromBinding, toBinding } = typeHelpers; + return { + get: createDefaultGetter({ fromBinding, itemType }), + // Directly setting by "index" to a Set is a no-op. + set: () => {}, + insert(set, value) { + assert.inTransaction(realm); + + try { + set.insertAny(toBinding(value)); + } catch (err) { + // Optimize for the valid cases by not guarding for the unsupported nested collections upfront. + throw transformError(err); + } + }, + }; +} + +function transformError(err: unknown) { + const message = err instanceof Error ? err.message : ""; + if (message?.includes("'Array' to a Mixed") || message?.includes("'List' to a Mixed")) { + return new Error("Lists within a Set are not supported."); + } + if (message?.includes("'Object' to a Mixed") || message?.includes("'Dictionary' to a Mixed")) { + return new Error("Dictionaries within a Set are not supported."); + } + return err; +} diff --git a/packages/realm/src/deprecated-global.ts b/packages/realm/src/deprecated-global.ts index 14c52f0e6c..fe9804ed8b 100644 --- a/packages/realm/src/deprecated-global.ts +++ b/packages/realm/src/deprecated-global.ts @@ -16,8 +16,10 @@ // //////////////////////////////////////////////////////////////////////////// -import { Realm as RealmConstructor, flags, safeGlobalThis } from "./internal"; -import * as internal from "./internal"; +import { Realm as RealmConstructor } from "./Realm"; +import { safeGlobalThis } from "./safeGlobalThis"; +import { flags } from "./flags"; +import * as ns from "./namespace"; let warnedAboutGlobalRealmUse = false; Object.defineProperty(safeGlobalThis, "Realm", { @@ -57,157 +59,157 @@ declare global { */ export namespace Realm { export import Realm = RealmConstructor; - export import flags = internal.flags; + export import flags = ns.flags; - export import Object = internal.RealmObject; - export import App = internal.App; - export import Auth = internal.Auth; - export import BSON = internal.BSON; - export import Types = internal.Types; - export import Services = internal.Services; + export import Object = ns.RealmObject; + export import App = ns.App; + export import Auth = ns.Auth; + export import BSON = ns.BSON; + export import Types = ns.Types; + export import Services = ns.Services; - export import index = internal.index; - export import mapTo = internal.mapTo; - export import kmToRadians = internal.kmToRadians; - export import miToRadians = internal.miToRadians; + export import index = ns.index; + export import mapTo = ns.mapTo; + export import kmToRadians = ns.kmToRadians; + export import miToRadians = ns.miToRadians; - export import AnyCollection = internal.AnyCollection; - export import AnyDictionary = internal.AnyDictionary; - export import AnyList = internal.AnyList; - export import AnyRealmObject = internal.AnyRealmObject; - export import AnyResults = internal.AnyResults; - export import AnyUser = internal.AnyUser; - export import ApiKey = internal.ApiKey; - export import AppChangeCallback = internal.AppChangeCallback; - export import AssertionError = internal.AssertionError; - export import AppConfiguration = internal.AppConfiguration; - export import AppServicesFunction = internal.AppServicesFunction; - export import BaseConfiguration = internal.BaseConfiguration; - export import BaseObjectSchema = internal.BaseObjectSchema; - export import BaseSyncConfiguration = internal.BaseSyncConfiguration; - export import CanonicalGeoPoint = internal.CanonicalGeoPoint; - export import CanonicalGeoPolygon = internal.CanonicalGeoPolygon; - export import CanonicalObjectSchema = internal.CanonicalObjectSchema; - export import CanonicalPropertiesTypes = internal.CanonicalPropertiesTypes; - export import CanonicalPropertySchema = internal.CanonicalPropertySchema; - export import ClientResetAfterCallback = internal.ClientResetAfterCallback; - export import ClientResetBeforeCallback = internal.ClientResetBeforeCallback; - export import ClientResetConfig = internal.ClientResetConfig; - export import ClientResetDiscardUnsyncedChangesConfiguration = internal.ClientResetDiscardUnsyncedChangesConfiguration; - export import ClientResetFallbackCallback = internal.ClientResetFallbackCallback; - export import ClientResetManualConfiguration = internal.ClientResetManualConfiguration; - export import ClientResetMode = internal.ClientResetMode; - export import ClientResetRecoverOrDiscardUnsyncedChangesConfiguration = internal.ClientResetRecoverOrDiscardUnsyncedChangesConfiguration; - export import ClientResetRecoverUnsyncedChangesConfiguration = internal.ClientResetRecoverUnsyncedChangesConfiguration; - export import Collection = internal.Collection; - export import CollectionChangeCallback = internal.CollectionChangeCallback; - export import CollectionChangeSet = internal.CollectionChangeSet; - export import CollectionPropertyTypeName = internal.CollectionPropertyTypeName; - export import CompensatingWriteError = internal.CompensatingWriteError; - export import CompensatingWriteInfo = internal.CompensatingWriteInfo; - export import Configuration = internal.Configuration; - export import ConfigurationWithoutSync = internal.ConfigurationWithoutSync; - export import ConfigurationWithSync = internal.ConfigurationWithSync; - export import ConnectionNotificationCallback = internal.ConnectionNotificationCallback; - export import ConnectionState = internal.ConnectionState; - export import Credentials = internal.Credentials; - export import DefaultFunctionsFactory = internal.DefaultFunctionsFactory; - export import DefaultUserProfileData = internal.DefaultUserProfileData; - export import Dictionary = internal.Dictionary; - export import DictionaryChangeCallback = internal.DictionaryChangeCallback; - export import DictionaryChangeSet = internal.DictionaryChangeSet; - export import ErrorCallback = internal.ErrorCallback; - export import FlexibleSyncConfiguration = internal.FlexibleSyncConfiguration; - export import GeoBox = internal.GeoBox; - export import GeoCircle = internal.GeoCircle; - export import GeoPoint = internal.GeoPoint; - export import GeoPolygon = internal.GeoPolygon; - export import GeoPosition = internal.GeoPosition; - export import IndexDecorator = internal.IndexDecorator; - export import IndexedType = internal.IndexedType; - export import InitialSubscriptions = internal.InitialSubscriptions; - export import List = internal.List; - export import LocalAppConfiguration = internal.LocalAppConfiguration; - export import Logger = internal.Logger; - export import LoggerCallback = internal.LoggerCallback; - export import MapToDecorator = internal.MapToDecorator; - export import Metadata = internal.Metadata; - export import MetadataMode = internal.MetadataMode; - export import MigrationCallback = internal.MigrationCallback; - export import MigrationOptions = internal.MigrationOptions; - export import Mixed = internal.Types.Mixed; - export import MongoDB = internal.MongoDB; - export import MongoDBService = internal.MongoDBService; - export import NumericLogLevel = internal.NumericLogLevel; - export import ObjectChangeCallback = internal.ObjectChangeCallback; - export import ObjectChangeSet = internal.ObjectChangeSet; - export import ObjectSchema = internal.ObjectSchema; - export import ObjectType = internal.ObjectType; - export import OpenRealmBehaviorConfiguration = internal.OpenRealmBehaviorConfiguration; - export import OpenRealmBehaviorType = internal.OpenRealmBehaviorType; - export import OpenRealmTimeOutBehavior = internal.OpenRealmTimeOutBehavior; - export import OrderedCollection = internal.OrderedCollection; - export import PartitionSyncConfiguration = internal.PartitionSyncConfiguration; - export import PrimaryKey = internal.PrimaryKey; - export import PrimitivePropertyTypeName = internal.PrimitivePropertyTypeName; - export import ProgressDirection = internal.ProgressDirection; - export import ProgressMode = internal.ProgressMode; - export import ProgressNotificationCallback = internal.ProgressNotificationCallback; - export import ProgressRealmPromise = internal.ProgressRealmPromise; - export import PropertiesTypes = internal.PropertiesTypes; - export import PropertySchema = internal.PropertySchema; - export import PropertySchemaParseError = internal.PropertySchemaParseError; - export import PropertySchemaShorthand = internal.PropertySchemaShorthand; - export import PropertySchemaStrict = internal.PropertySchemaStrict; - export import PropertyTypeName = internal.PropertyTypeName; - export import ProviderType = internal.ProviderType; - export import ProxyType = internal.ProxyType; - export import RealmEvent = internal.RealmEvent; - export import RealmEventName = internal.RealmEventName; - export import RealmListenerCallback = internal.RealmListenerCallback; - export import RealmObjectConstructor = internal.RealmObjectConstructor; - export import RelationshipPropertyTypeName = internal.RelationshipPropertyTypeName; - export import Results = internal.Results; - export import SchemaParseError = internal.SchemaParseError; - export import SecretApiKey = internal.SecretApiKey; - export import SessionState = internal.SessionState; - export import SessionStopPolicy = internal.SessionStopPolicy; - export import Set = internal.RealmSet; - export import SortDescriptor = internal.SortDescriptor; - export import SSLConfiguration = internal.SSLConfiguration; - export import SSLVerifyCallback = internal.SSLVerifyCallback; - export import SSLVerifyObject = internal.SSLVerifyObject; - export import SubscriptionSetState = internal.SubscriptionSetState; - export import SyncConfiguration = internal.SyncConfiguration; - export import SyncError = internal.SyncError; - export import SyncProxyConfig = internal.SyncProxyConfig; - export import TypeAssertionError = internal.TypeAssertionError; - export import Unmanaged = internal.Unmanaged; - export import UpdateMode = internal.UpdateMode; - export import User = internal.User; - export import UserChangeCallback = internal.UserChangeCallback; - export import UserIdentity = internal.UserIdentity; - export import UserState = internal.UserState; - export import WaitForSync = internal.WaitForSync; - export import WatchOptionsFilter = internal.WatchOptionsFilter; - export import WatchOptionsIds = internal.WatchOptionsIds; + export import AnyCollection = ns.AnyCollection; + export import AnyDictionary = ns.AnyDictionary; + export import AnyList = ns.AnyList; + export import AnyRealmObject = ns.AnyRealmObject; + export import AnyResults = ns.AnyResults; + export import AnyUser = ns.AnyUser; + export import ApiKey = ns.ApiKey; + export import AppChangeCallback = ns.AppChangeCallback; + export import AssertionError = ns.AssertionError; + export import AppConfiguration = ns.AppConfiguration; + export import AppServicesFunction = ns.AppServicesFunction; + export import BaseConfiguration = ns.BaseConfiguration; + export import BaseObjectSchema = ns.BaseObjectSchema; + export import BaseSyncConfiguration = ns.BaseSyncConfiguration; + export import CanonicalGeoPoint = ns.CanonicalGeoPoint; + export import CanonicalGeoPolygon = ns.CanonicalGeoPolygon; + export import CanonicalObjectSchema = ns.CanonicalObjectSchema; + export import CanonicalPropertiesTypes = ns.CanonicalPropertiesTypes; + export import CanonicalPropertySchema = ns.CanonicalPropertySchema; + export import ClientResetAfterCallback = ns.ClientResetAfterCallback; + export import ClientResetBeforeCallback = ns.ClientResetBeforeCallback; + export import ClientResetConfig = ns.ClientResetConfig; + export import ClientResetDiscardUnsyncedChangesConfiguration = ns.ClientResetDiscardUnsyncedChangesConfiguration; + export import ClientResetFallbackCallback = ns.ClientResetFallbackCallback; + export import ClientResetManualConfiguration = ns.ClientResetManualConfiguration; + export import ClientResetMode = ns.ClientResetMode; + export import ClientResetRecoverOrDiscardUnsyncedChangesConfiguration = ns.ClientResetRecoverOrDiscardUnsyncedChangesConfiguration; + export import ClientResetRecoverUnsyncedChangesConfiguration = ns.ClientResetRecoverUnsyncedChangesConfiguration; + export import Collection = ns.Collection; + export import CollectionChangeCallback = ns.CollectionChangeCallback; + export import CollectionChangeSet = ns.CollectionChangeSet; + export import CollectionPropertyTypeName = ns.CollectionPropertyTypeName; + export import CompensatingWriteError = ns.CompensatingWriteError; + export import CompensatingWriteInfo = ns.CompensatingWriteInfo; + export import Configuration = ns.Configuration; + export import ConfigurationWithoutSync = ns.ConfigurationWithoutSync; + export import ConfigurationWithSync = ns.ConfigurationWithSync; + export import ConnectionNotificationCallback = ns.ConnectionNotificationCallback; + export import ConnectionState = ns.ConnectionState; + export import Credentials = ns.Credentials; + export import DefaultFunctionsFactory = ns.DefaultFunctionsFactory; + export import DefaultUserProfileData = ns.DefaultUserProfileData; + export import Dictionary = ns.Dictionary; + export import DictionaryChangeCallback = ns.DictionaryChangeCallback; + export import DictionaryChangeSet = ns.DictionaryChangeSet; + export import ErrorCallback = ns.ErrorCallback; + export import FlexibleSyncConfiguration = ns.FlexibleSyncConfiguration; + export import GeoBox = ns.GeoBox; + export import GeoCircle = ns.GeoCircle; + export import GeoPoint = ns.GeoPoint; + export import GeoPolygon = ns.GeoPolygon; + export import GeoPosition = ns.GeoPosition; + export import IndexDecorator = ns.IndexDecorator; + export import IndexedType = ns.IndexedType; + export import InitialSubscriptions = ns.InitialSubscriptions; + export import List = ns.List; + export import LocalAppConfiguration = ns.LocalAppConfiguration; + export import Logger = ns.Logger; + export import LoggerCallback = ns.LoggerCallback; + export import MapToDecorator = ns.MapToDecorator; + export import Metadata = ns.Metadata; + export import MetadataMode = ns.MetadataMode; + export import MigrationCallback = ns.MigrationCallback; + export import MigrationOptions = ns.MigrationOptions; + export import Mixed = ns.Types.Mixed; + export import MongoDB = ns.MongoDB; + export import MongoDBService = ns.MongoDBService; + export import NumericLogLevel = ns.NumericLogLevel; + export import ObjectChangeCallback = ns.ObjectChangeCallback; + export import ObjectChangeSet = ns.ObjectChangeSet; + export import ObjectSchema = ns.ObjectSchema; + export import ObjectType = ns.ObjectType; + export import OpenRealmBehaviorConfiguration = ns.OpenRealmBehaviorConfiguration; + export import OpenRealmBehaviorType = ns.OpenRealmBehaviorType; + export import OpenRealmTimeOutBehavior = ns.OpenRealmTimeOutBehavior; + export import OrderedCollection = ns.OrderedCollection; + export import PartitionSyncConfiguration = ns.PartitionSyncConfiguration; + export import PrimaryKey = ns.PrimaryKey; + export import PrimitivePropertyTypeName = ns.PrimitivePropertyTypeName; + export import ProgressDirection = ns.ProgressDirection; + export import ProgressMode = ns.ProgressMode; + export import ProgressNotificationCallback = ns.ProgressNotificationCallback; + export import ProgressRealmPromise = ns.ProgressRealmPromise; + export import PropertiesTypes = ns.PropertiesTypes; + export import PropertySchema = ns.PropertySchema; + export import PropertySchemaParseError = ns.PropertySchemaParseError; + export import PropertySchemaShorthand = ns.PropertySchemaShorthand; + export import PropertySchemaStrict = ns.PropertySchemaStrict; + export import PropertyTypeName = ns.PropertyTypeName; + export import ProviderType = ns.ProviderType; + export import ProxyType = ns.ProxyType; + export import RealmEvent = ns.RealmEvent; + export import RealmEventName = ns.RealmEventName; + export import RealmListenerCallback = ns.RealmListenerCallback; + export import RealmObjectConstructor = ns.RealmObjectConstructor; + export import RelationshipPropertyTypeName = ns.RelationshipPropertyTypeName; + export import Results = ns.Results; + export import SchemaParseError = ns.SchemaParseError; + export import SecretApiKey = ns.SecretApiKey; + export import SessionState = ns.SessionState; + export import SessionStopPolicy = ns.SessionStopPolicy; + export import Set = ns.RealmSet; + export import SortDescriptor = ns.SortDescriptor; + export import SSLConfiguration = ns.SSLConfiguration; + export import SSLVerifyCallback = ns.SSLVerifyCallback; + export import SSLVerifyObject = ns.SSLVerifyObject; + export import SubscriptionSetState = ns.SubscriptionSetState; + export import SyncConfiguration = ns.SyncConfiguration; + export import SyncError = ns.SyncError; + export import SyncProxyConfig = ns.SyncProxyConfig; + export import TypeAssertionError = ns.TypeAssertionError; + export import Unmanaged = ns.Unmanaged; + export import UpdateMode = ns.UpdateMode; + export import User = ns.User; + export import UserChangeCallback = ns.UserChangeCallback; + export import UserIdentity = ns.UserIdentity; + export import UserState = ns.UserState; + export import WaitForSync = ns.WaitForSync; + export import WatchOptionsFilter = ns.WatchOptionsFilter; + export import WatchOptionsIds = ns.WatchOptionsIds; // Deprecated exports below - /** @deprecated Will be removed in v13.0.0. Please use {@link internal.AppServicesFunction | AppServicesFunction} */ - export import RealmFunction = internal.AppServicesFunction; - /** @deprecated Will be removed in v13.0.0. Please use {@link internal.CanonicalPropertySchema | CanonicalPropertySchema} */ - export import CanonicalObjectSchemaProperty = internal.CanonicalPropertySchema; - /** @deprecated Will be removed in v13.0.0. Please use {@link internal.ClientResetRecoverUnsyncedChangesConfiguration | ClientResetRecoverUnsyncedChangesConfiguration} */ - export import ClientResetRecoveryConfiguration = internal.ClientResetRecoverUnsyncedChangesConfiguration; - /** @deprecated Will be removed in v13.0.0. Please use {@link internal.PropertySchema | PropertySchema} */ - export import ObjectSchemaProperty = internal.PropertySchema; - /** @deprecated Will be removed in v13.0.0. Please use {@link internal.RealmObjectConstructor | RealmObjectConstructor} */ - export import ObjectClass = internal.RealmObjectConstructor; - /** @deprecated Will be removed in v13.0.0. Please use {@link internal.PropertyTypeName | PropertyTypeName} */ - export import PropertyType = internal.PropertyTypeName; - /** @deprecated Use the another {@link internal.ClientResetMode | ClientResetMode} than {@link internal.ClientResetMode.Manual | ClientResetMode.Manual}. */ - export import ClientResetError = internal.ClientResetError; + /** @deprecated Will be removed in v13.0.0. Please use {@link ns.AppServicesFunction | AppServicesFunction} */ + export import RealmFunction = ns.AppServicesFunction; + /** @deprecated Will be removed in v13.0.0. Please use {@link ns.CanonicalPropertySchema | CanonicalPropertySchema} */ + export import CanonicalObjectSchemaProperty = ns.CanonicalPropertySchema; + /** @deprecated Will be removed in v13.0.0. Please use {@link ns.ClientResetRecoverUnsyncedChangesConfiguration | ClientResetRecoverUnsyncedChangesConfiguration} */ + export import ClientResetRecoveryConfiguration = ns.ClientResetRecoverUnsyncedChangesConfiguration; + /** @deprecated Will be removed in v13.0.0. Please use {@link ns.PropertySchema | PropertySchema} */ + export import ObjectSchemaProperty = ns.PropertySchema; + /** @deprecated Will be removed in v13.0.0. Please use {@link ns.RealmObjectConstructor | RealmObjectConstructor} */ + export import ObjectClass = ns.RealmObjectConstructor; + /** @deprecated Will be removed in v13.0.0. Please use {@link ns.PropertyTypeName | PropertyTypeName} */ + export import PropertyType = ns.PropertyTypeName; + /** @deprecated Use the another {@link ns.ClientResetMode | ClientResetMode} than {@link ns.ClientResetMode.Manual | ClientResetMode.Manual}. */ + export import ClientResetError = ns.ClientResetError; /** @deprecated See https://www.mongodb.com/docs/atlas/app-services/reference/push-notifications/ */ - export import PushClient = internal.PushClient; + export import PushClient = ns.PushClient; } } diff --git a/packages/realm/src/errors.ts b/packages/realm/src/errors.ts index 2a4ef009e8..4e4f8d24d9 100644 --- a/packages/realm/src/errors.ts +++ b/packages/realm/src/errors.ts @@ -16,7 +16,10 @@ // //////////////////////////////////////////////////////////////////////////// -import { ClientResetMode, Configuration, PrimaryKey, assert, binding } from "./internal"; +import type { binding } from "../binding"; +import type { PrimaryKey } from "./schema"; +import type { Configuration } from "./Configuration"; +import type { ClientResetMode } from "./app-services/SyncConfiguration"; export class AssertionError extends Error { /** @internal */ @@ -227,8 +230,7 @@ export class CompensatingWriteError extends SyncError { constructor(error: binding.SyncError) { super(error); for (const { objectName, primaryKey, reason } of error.compensatingWritesInfo) { - assert.primaryKey(primaryKey); - this.writes.push({ objectName, reason, primaryKey }); + this.writes.push({ objectName, reason, primaryKey: primaryKey as PrimaryKey }); } } } diff --git a/packages/realm/src/index.ts b/packages/realm/src/index.ts index 1b50f8bff6..cc9952ee15 100644 --- a/packages/realm/src/index.ts +++ b/packages/realm/src/index.ts @@ -18,3 +18,5 @@ import { Realm } from "./Realm"; export = Realm; + +import "./deprecated-global"; diff --git a/packages/realm/src/indirect.ts b/packages/realm/src/indirect.ts new file mode 100644 index 0000000000..c888734244 --- /dev/null +++ b/packages/realm/src/indirect.ts @@ -0,0 +1,76 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2024 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. +// +//////////////////////////////////////////////////////////////////////////// + +import type { Realm } from "./Realm"; +import type { Results } from "./Results"; +import type { List } from "./List"; +import type { Dictionary } from "./Dictionary"; +import type { RealmSet } from "./Set"; +import type { OrderedCollection } from "./OrderedCollection"; +import type { RealmObject } from "./Object"; +import type { Collection } from "./Collection"; +import type { App } from "./app-services/App"; +import type { User } from "./app-services/User"; + +type Indirects = { + Realm: typeof Realm; + Collection: typeof Collection; + OrderedCollection: typeof OrderedCollection; + Results: typeof Results; + List: typeof List; + Dictionary: typeof Dictionary; + Set: typeof RealmSet; + Object: typeof RealmObject; + App: typeof App; + User: typeof User; +}; + +/** + * Values that can be dependent on at runtime without eagerly loading it into the module. + * Use this as a last resort only to break cyclic imports. + * @internal + */ +export const indirect = {} as Indirects; + +const THROW_ON_ACCESS_HANDLER: ProxyHandler = { + get(_target, prop) { + if (typeof prop === "string") { + throw new AccessError(prop); + } + }, +}; + +// Setting a prototype which throws if an indirect value gets accessed at runtime before it's injected +Object.setPrototypeOf(indirect, new Proxy({}, THROW_ON_ACCESS_HANDLER)); + +class AccessError extends Error { + constructor(name: string) { + super(`Accessing indirect ${name} before it got injected`); + } +} + +/** + * Injects a value that can be dependent on at runtime without eagerly loading it into the module. + * @internal + */ +export function injectIndirect(name: Name, value: (typeof indirect)[typeof name]) { + Object.defineProperty(indirect, name, { + value, + writable: false, + }); +} diff --git a/packages/realm/src/internal.ts b/packages/realm/src/namespace.ts similarity index 66% rename from packages/realm/src/internal.ts rename to packages/realm/src/namespace.ts index 1a7cfef004..89342327ee 100644 --- a/packages/realm/src/internal.ts +++ b/packages/realm/src/namespace.ts @@ -16,51 +16,10 @@ // //////////////////////////////////////////////////////////////////////////// -/** - * @module - * We're following [the internal module pattern](https://medium.com/visual-development/how-to-fix-nasty-circular-dependency-issues-once-and-for-all-in-javascript-typescript-a04c987cf0de) to control of the order of code when bundled. - */ - -/** @internal */ -export * from "./debug"; -export * from "./safeGlobalThis"; - -/** @internal */ -export * from "./platform"; - export * from "./flags"; export * from "./bson"; export * from "./errors"; export * from "./decorators"; -/** @internal */ -export * from "./assert"; -/** @internal */ -export * from "./ranges"; -/** @internal */ -export * from "./async-iterator-from-response"; -/** @internal */ -export * from "./Listeners"; -/** @internal */ -export * from "./JSONCacheMap"; -/** @internal */ -export * from "./TimeoutPromise"; - -/** @internal */ -export * from "./PropertyHelpers"; -/** @internal */ -export * from "./PropertyMap"; -/** @internal */ -export * from "./ClassHelpers"; -/** @internal */ -export * from "./ClassMap"; -/** @internal */ -export * from "./TypeHelpers"; -/** @internal */ -export { mixedToBinding } from "./type-helpers/Mixed"; -/** @internal */ -export { toArrayBuffer } from "./type-helpers/array-buffer"; -/** @internal */ -export type { TypeHelpers, TypeOptions } from "./type-helpers/types"; export * from "./PromiseHandle"; @@ -108,5 +67,3 @@ export * from "./ProgressRealmPromise"; export * from "./Unmanaged"; export * from "./schema"; - -import "./deprecated-global"; diff --git a/packages/realm/src/platform/binding-patch.ts b/packages/realm/src/platform/binding-patch.ts index 60b8c432db..2009a5c298 100644 --- a/packages/realm/src/platform/binding-patch.ts +++ b/packages/realm/src/platform/binding-patch.ts @@ -16,7 +16,8 @@ // //////////////////////////////////////////////////////////////////////////// -import { AbortSignal, fetch } from "@realm/fetch"; +import type { fetch } from "@realm/fetch"; +import { AbortSignal } from "@realm/fetch"; /** @internal */ import type * as binding from "../../binding/generated/native"; diff --git a/packages/realm/src/platform/node/custom-inspect.ts b/packages/realm/src/platform/node/custom-inspect.ts index 0548ad855b..b1b7d648f0 100644 --- a/packages/realm/src/platform/node/custom-inspect.ts +++ b/packages/realm/src/platform/node/custom-inspect.ts @@ -15,9 +15,16 @@ // limitations under the License. // //////////////////////////////////////////////////////////////////////////// -import { InspectOptionsStylized, inspect } from "node:util"; -import { Collection, Dictionary, List, RealmObject, RealmSet, Results } from "../../internal"; +import type { InspectOptionsStylized } from "node:util"; +import { inspect } from "node:util"; + +import { Collection } from "../../Collection"; +import { Dictionary } from "../../Dictionary"; +import { List } from "../../List"; +import { RealmSet } from "../../Set"; +import { Results } from "../../Results"; +import { RealmObject } from "../../Object"; type CustomInspectFunction = (this: T, depth: number, options: InspectOptionsStylized) => void; diff --git a/packages/realm/src/platform/node/index.ts b/packages/realm/src/platform/node/index.ts index ecaf4eca95..dfbef65892 100644 --- a/packages/realm/src/platform/node/index.ts +++ b/packages/realm/src/platform/node/index.ts @@ -20,8 +20,10 @@ import "./binding"; import "./fs"; import "./device-info"; import "./sync-proxy-config"; -import "./custom-inspect"; import "./garbage-collection"; import { Realm } from "../../Realm"; export = Realm; + +import "./custom-inspect"; +import "../../deprecated-global"; diff --git a/packages/realm/src/platform/react-native/index.ts b/packages/realm/src/platform/react-native/index.ts index 4eff6da924..5c2b9f043f 100644 --- a/packages/realm/src/platform/react-native/index.ts +++ b/packages/realm/src/platform/react-native/index.ts @@ -30,3 +30,5 @@ binding.RealmCoordinator.clearAllCaches(); binding.App.clearCachedApps(); export = Realm; + +import "../../deprecated-global"; diff --git a/packages/realm/src/property-accessors/Array.ts b/packages/realm/src/property-accessors/Array.ts index 76dccbadce..2f687c2f8b 100644 --- a/packages/realm/src/property-accessors/Array.ts +++ b/packages/realm/src/property-accessors/Array.ts @@ -16,17 +16,14 @@ // //////////////////////////////////////////////////////////////////////////// -import { - List, - Results, - TypeAssertionError, - assert, - binding, - createListAccessor, - createResultsAccessor, - getTypeHelpers, - toItemType, -} from "../internal"; +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { createListAccessor } from "../collection-accessors/List"; +import { createResultsAccessor } from "../collection-accessors/Results"; +import { TypeAssertionError } from "../errors"; +import { List } from "../List"; +import { Results } from "../Results"; +import { getTypeHelpers, toItemType } from "../TypeHelpers"; import type { PropertyAccessor, PropertyOptions } from "./types"; /** @internal */ diff --git a/packages/realm/src/property-accessors/Dictionary.ts b/packages/realm/src/property-accessors/Dictionary.ts index 25b2d125a7..64f0819b39 100644 --- a/packages/realm/src/property-accessors/Dictionary.ts +++ b/packages/realm/src/property-accessors/Dictionary.ts @@ -16,16 +16,13 @@ // //////////////////////////////////////////////////////////////////////////// -import { - Dictionary, - TypeAssertionError, - assert, - binding, - createDictionaryAccessor, - getTypeHelpers, - toItemType, -} from "../internal"; +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { TypeAssertionError } from "../errors"; +import { Dictionary } from "../Dictionary"; +import { getTypeHelpers, toItemType } from "../TypeHelpers"; import type { PropertyAccessor, PropertyOptions } from "./types"; +import { createDictionaryAccessor } from "../collection-accessors/Dictionary"; /** @internal */ export function createDictionaryPropertyAccessor({ diff --git a/packages/realm/src/property-accessors/Int.ts b/packages/realm/src/property-accessors/Int.ts index 54886da435..10450c44e6 100644 --- a/packages/realm/src/property-accessors/Int.ts +++ b/packages/realm/src/property-accessors/Int.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import { Counter } from "../internal"; +import { Counter } from "../Counter"; import { createDefaultPropertyAccessor } from "./default"; import type { PropertyAccessor, PropertyOptions } from "./types"; diff --git a/packages/realm/src/property-accessors/Mixed.ts b/packages/realm/src/property-accessors/Mixed.ts index 395e2ea997..e2155305e8 100644 --- a/packages/realm/src/property-accessors/Mixed.ts +++ b/packages/realm/src/property-accessors/Mixed.ts @@ -16,18 +16,16 @@ // //////////////////////////////////////////////////////////////////////////// +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { Dictionary } from "../Dictionary"; import { - Dictionary, - List, - assert, - binding, createDictionaryAccessor, - createListAccessor, insertIntoDictionaryOfMixed, - insertIntoListOfMixed, isJsOrRealmDictionary, - isJsOrRealmList, -} from "../internal"; +} from "../collection-accessors/Dictionary"; +import { List } from "../List"; +import { createListAccessor, insertIntoListOfMixed, isJsOrRealmList } from "../collection-accessors/List"; import { createDefaultPropertyAccessor } from "./default"; import type { PropertyAccessor, PropertyOptions } from "./types"; diff --git a/packages/realm/src/property-accessors/Object.ts b/packages/realm/src/property-accessors/Object.ts index fad9c3ca7c..a171dc0d66 100644 --- a/packages/realm/src/property-accessors/Object.ts +++ b/packages/realm/src/property-accessors/Object.ts @@ -16,7 +16,8 @@ // //////////////////////////////////////////////////////////////////////////// -import { assert, binding } from "../internal"; +import type { binding } from "../../binding"; +import { assert } from "../assert"; import { createDefaultPropertyAccessor } from "./default"; import type { PropertyAccessor, PropertyOptions } from "./types"; diff --git a/packages/realm/src/property-accessors/Set.ts b/packages/realm/src/property-accessors/Set.ts index dedf872d7e..940c53f048 100644 --- a/packages/realm/src/property-accessors/Set.ts +++ b/packages/realm/src/property-accessors/Set.ts @@ -16,8 +16,12 @@ // //////////////////////////////////////////////////////////////////////////// -import { RealmSet, assert, binding, createSetAccessor, getTypeHelpers, toItemType } from "../internal"; -import { PropertyAccessor, PropertyOptions } from "./types"; +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { RealmSet } from "../Set"; +import type { PropertyAccessor, PropertyOptions } from "./types"; +import { getTypeHelpers, toItemType } from "../TypeHelpers"; +import { createSetAccessor } from "../collection-accessors/Set"; /** @internal */ export function createSetPropertyAccessor({ diff --git a/packages/realm/src/property-accessors/default.ts b/packages/realm/src/property-accessors/default.ts index 3661e90700..6bd293accf 100644 --- a/packages/realm/src/property-accessors/default.ts +++ b/packages/realm/src/property-accessors/default.ts @@ -16,8 +16,9 @@ // //////////////////////////////////////////////////////////////////////////// -import { assert, binding } from "../internal"; -import { PropertyAccessor, PropertyOptions } from "./types"; +import type { binding } from "../../binding"; +import { assert } from "../assert"; +import type { PropertyAccessor, PropertyOptions } from "./types"; /** @internal */ export function createDefaultPropertyAccessor({ diff --git a/packages/realm/src/property-accessors/types.ts b/packages/realm/src/property-accessors/types.ts index 816f240de2..05c6194f0d 100644 --- a/packages/realm/src/property-accessors/types.ts +++ b/packages/realm/src/property-accessors/types.ts @@ -16,8 +16,12 @@ // //////////////////////////////////////////////////////////////////////////// -import { ClassHelpers, ListAccessor, PresentationPropertyTypeName, Realm, binding } from "../internal"; -import type { TypeHelpers } from "../type-helpers/types"; +import type { binding } from "../../binding"; +import type { ClassHelpers } from "../ClassHelpers"; +import type { ListAccessor } from "../collection-accessors/List"; +import type { Realm } from "../Realm"; +import type { PresentationPropertyTypeName } from "../schema"; +import type { TypeHelpers } from "../TypeHelpers"; /** @internal */ export type PropertyContext = binding.Property & { diff --git a/packages/realm/src/schema/from-binding.ts b/packages/realm/src/schema/from-binding.ts index 020093ce90..6d260f58f4 100644 --- a/packages/realm/src/schema/from-binding.ts +++ b/packages/realm/src/schema/from-binding.ts @@ -16,14 +16,15 @@ // //////////////////////////////////////////////////////////////////////////// -import { assert, binding } from "../internal"; +import { binding } from "../../binding"; +import { assert } from "../assert"; type BindingObjectSchema = binding.ObjectSchema; type BindingProperty = binding.Property; import TableType = binding.TableType; import BindingPropertyType = binding.PropertyType; -import { CanonicalObjectSchema, CanonicalPropertySchema, PropertyTypeName } from "./types"; +import type { CanonicalObjectSchema, CanonicalPropertySchema, PropertyTypeName } from "./types"; const TYPE_MAPPINGS: Record = { [BindingPropertyType.Int]: "int", diff --git a/packages/realm/src/schema/normalize.ts b/packages/realm/src/schema/normalize.ts index cfee8c6df7..143394d71a 100644 --- a/packages/realm/src/schema/normalize.ts +++ b/packages/realm/src/schema/normalize.ts @@ -16,25 +16,23 @@ // //////////////////////////////////////////////////////////////////////////// -import { +import { assert } from "../assert"; +import { flags } from "../flags"; +import { ObjectSchemaParseError, PropertySchemaParseError, SchemaParseError } from "../errors"; +import type { CanonicalObjectSchema, CanonicalPropertySchema, CollectionPropertyTypeName, ObjectSchema, - ObjectSchemaParseError, PresentationPropertyTypeName, PrimitivePropertyTypeName, PropertiesTypes, PropertySchema, - PropertySchemaParseError, PropertySchemaShorthand, PropertyTypeName, RealmObjectConstructor, - SchemaParseError, UserTypeName, - assert, - flags, -} from "../internal"; +} from "../schema"; type PropertyInfo = { readonly objectName: string; diff --git a/packages/realm/src/schema/to-binding.ts b/packages/realm/src/schema/to-binding.ts index f72ae32ff8..0b4fda5e22 100644 --- a/packages/realm/src/schema/to-binding.ts +++ b/packages/realm/src/schema/to-binding.ts @@ -16,7 +16,9 @@ // //////////////////////////////////////////////////////////////////////////// -import { CanonicalObjectSchema, CanonicalPropertySchema, PropertyTypeName, assert, binding } from "../internal"; +import { assert } from "../assert"; +import { binding } from "../../binding"; +import type { CanonicalObjectSchema, CanonicalPropertySchema, PropertyTypeName } from "../schema"; type BindingObjectSchema = binding.ObjectSchema_Relaxed; type BindingProperty = binding.Property_Relaxed; diff --git a/packages/realm/src/schema/types.ts b/packages/realm/src/schema/types.ts index ce5e952f7c..33183d0341 100644 --- a/packages/realm/src/schema/types.ts +++ b/packages/realm/src/schema/types.ts @@ -16,7 +16,9 @@ // //////////////////////////////////////////////////////////////////////////// -import { BSON, Realm, RealmObject } from "../internal"; +import type { BSON } from "../bson"; +import type { Realm } from "../Realm"; +import type { RealmObject } from "../Object"; export type DefaultObject = Record; /* eslint-disable-next-line @typescript-eslint/no-explicit-any -- Using `any` instead of `unknown` here to make it easier to pass */ diff --git a/packages/realm/src/schema/validate.ts b/packages/realm/src/schema/validate.ts index 1104fec4f0..d70ea5e84b 100644 --- a/packages/realm/src/schema/validate.ts +++ b/packages/realm/src/schema/validate.ts @@ -16,19 +16,18 @@ // //////////////////////////////////////////////////////////////////////////// -import { +import { assert } from "../assert"; +import { ObjectSchemaParseError, PropertySchemaParseError } from "../errors"; +import { indirect } from "../indirect"; +import type { CanonicalObjectSchema, CanonicalPropertySchema, - Configuration, DefaultObject, ObjectSchema, - ObjectSchemaParseError, PropertySchema, - PropertySchemaParseError, - RealmObject, RealmObjectConstructor, - assert, -} from "../internal"; +} from "../schema"; +import type { Configuration } from "../Configuration"; // Need to use `CanonicalObjectSchema` rather than `ObjectSchema` due to some // integration tests using `openRealmHook()`. That function sets `this.realm` @@ -81,7 +80,7 @@ export function validateObjectSchema( if (typeof objectSchema === "function") { const clazz = objectSchema as unknown as DefaultObject; // We assert this later, but want a custom error message - if (!(objectSchema.prototype instanceof RealmObject)) { + if (!(objectSchema.prototype instanceof indirect.Object)) { const schemaName = clazz.schema && (clazz.schema as DefaultObject).name; if (typeof schemaName === "string" && schemaName !== objectSchema.name) { throw new TypeError( diff --git a/packages/realm/src/scripts/build/android.ts b/packages/realm/src/scripts/build/android.ts index d922b5d100..7d1f5c7f17 100644 --- a/packages/realm/src/scripts/build/android.ts +++ b/packages/realm/src/scripts/build/android.ts @@ -24,8 +24,8 @@ import path from "node:path"; import { spawnSync } from "node:child_process"; import assert from "node:assert"; +import type { Configuration } from "./common"; import { - Configuration, PACKAGE_PATH, REALM_CORE_LIBRARY_NAMES_ALLOWLIST, REALM_CORE_PATH, diff --git a/packages/realm/src/scripts/build/apple.ts b/packages/realm/src/scripts/build/apple.ts index e087d502ef..146c178912 100644 --- a/packages/realm/src/scripts/build/apple.ts +++ b/packages/realm/src/scripts/build/apple.ts @@ -26,7 +26,8 @@ import path from "node:path"; import { globSync } from "glob"; -import { ARCHIVE_INSTALL_PATH, SUPPORTED_PLATFORMS, XcodeSDKName, xcode } from "./xcode"; +import type { XcodeSDKName } from "./xcode"; +import { ARCHIVE_INSTALL_PATH, SUPPORTED_PLATFORMS, xcode } from "./xcode"; import { PACKAGE_PATH, REALM_CORE_LIBRARY_NAMES_ALLOWLIST, diff --git a/packages/realm/src/symbols.ts b/packages/realm/src/symbols.ts new file mode 100644 index 0000000000..25bbe60417 --- /dev/null +++ b/packages/realm/src/symbols.ts @@ -0,0 +1,21 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2024 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. +// +//////////////////////////////////////////////////////////////////////////// + +export const OBJECT_INTERNAL = Symbol("Object#internal"); +export const OBJECT_REALM = Symbol("Object#realm"); +export const OBJECT_HELPERS = Symbol("Object#helpers"); diff --git a/packages/realm/src/tests/collection-helpers.test.ts b/packages/realm/src/tests/collection-helpers.test.ts index b80cd2db43..1c1496ed38 100644 --- a/packages/realm/src/tests/collection-helpers.test.ts +++ b/packages/realm/src/tests/collection-helpers.test.ts @@ -18,7 +18,7 @@ import { expect } from "chai"; -import { isPOJO } from "../Dictionary"; +import { isPOJO } from "../collection-accessors/Dictionary"; describe("Collection helpers", () => { describe("isPOJO()", () => { diff --git a/packages/realm/src/tests/list.test.ts b/packages/realm/src/tests/list.test.ts index 14333514ee..c2b0f4f241 100644 --- a/packages/realm/src/tests/list.test.ts +++ b/packages/realm/src/tests/list.test.ts @@ -18,7 +18,8 @@ import { Realm } from "../Realm"; -import { RealmContext, closeRealm, generateTempRealmPath } from "./utils"; +import type { RealmContext } from "./utils"; +import { closeRealm, generateTempRealmPath } from "./utils"; describe("List", () => { beforeEach(function (this: RealmContext) { diff --git a/packages/realm/src/tests/milestone-2.test.ts b/packages/realm/src/tests/milestone-2.test.ts index ab10d5a6e0..1d394deb7d 100644 --- a/packages/realm/src/tests/milestone-2.test.ts +++ b/packages/realm/src/tests/milestone-2.test.ts @@ -20,8 +20,13 @@ import { assert, expect } from "chai"; import path from "path"; import fs from "fs"; -import { CanonicalObjectSchema, Realm, Object as RealmObject, Results } from "../index"; -import { REALMS_DIR, RealmContext, closeRealm, generateRandomInteger, generateTempRealmPath } from "./utils"; +import { Realm } from "../Realm"; +import { RealmObject } from "../Object"; +import { Results } from "../Results"; +import type { CanonicalObjectSchema } from "../schema"; + +import type { RealmContext } from "./utils"; +import { REALMS_DIR, closeRealm, generateRandomInteger, generateTempRealmPath } from "./utils"; type Person = { name: string; age?: number }; type PersonWithFriend = { name: string; age?: number; bestFriend: Person | null }; diff --git a/packages/realm/src/tests/milestone-3.test.ts b/packages/realm/src/tests/milestone-3.test.ts index 57d8381acf..bbb87e270d 100644 --- a/packages/realm/src/tests/milestone-3.test.ts +++ b/packages/realm/src/tests/milestone-3.test.ts @@ -18,8 +18,11 @@ import { expect } from "chai"; -import { ObjectChangeSet, Realm, Results } from "../index"; -import { RealmContext, closeRealm, generateTempRealmPath } from "./utils"; +import { Realm } from "../Realm"; +import type { ObjectChangeSet } from "../ObjectListeners"; +import { Results } from "../Results"; +import type { RealmContext } from "./utils"; +import { closeRealm, generateTempRealmPath } from "./utils"; describe("Milestone #3", () => { describe("Register a listener on an object and get notified of changes", () => { diff --git a/packages/realm/src/tests/milestone-4.test.ts b/packages/realm/src/tests/milestone-4.test.ts index 24d73889d8..6857c8e20b 100644 --- a/packages/realm/src/tests/milestone-4.test.ts +++ b/packages/realm/src/tests/milestone-4.test.ts @@ -18,8 +18,11 @@ import { expect } from "chai"; -import { Realm, Object as RealmObject, Results } from "../index"; -import { RealmContext, closeRealm, generateTempRealmPath } from "./utils"; +import { Realm } from "../Realm"; +import { RealmObject } from "../Object"; +import { Results } from "../Results"; +import type { RealmContext } from "./utils"; +import { closeRealm, generateTempRealmPath } from "./utils"; type Person = { name: string; age: number; bestFriend: Person | null }; diff --git a/packages/realm/src/tests/milestone-5.test.ts b/packages/realm/src/tests/milestone-5.test.ts index dc2b141e0e..31ea9747ff 100644 --- a/packages/realm/src/tests/milestone-5.test.ts +++ b/packages/realm/src/tests/milestone-5.test.ts @@ -20,8 +20,12 @@ import { expect } from "chai"; import { inspect } from "node:util"; import { Decimal128, ObjectId, UUID } from "bson"; -import { List, PropertySchema, PropertyTypeName, Realm, Object as RealmObject } from "../index"; -import { RealmContext, closeRealm, generateTempRealmPath } from "./utils"; +import { Realm } from "../Realm"; +import { RealmObject } from "../Object"; +import { List } from "../List"; +import type { PropertySchema, PropertyTypeName } from "../schema"; +import type { RealmContext } from "./utils"; +import { closeRealm, generateTempRealmPath } from "./utils"; type ValueFunction = (realm: Realm) => T; type TestFunction = (result: unknown, input: T) => boolean; diff --git a/packages/realm/src/tests/platform.test.ts b/packages/realm/src/tests/platform.test.ts index d77a975178..5762a778e2 100644 --- a/packages/realm/src/tests/platform.test.ts +++ b/packages/realm/src/tests/platform.test.ts @@ -20,7 +20,7 @@ import { isAbsolute } from "node:path"; import { existsSync } from "node:fs"; import { expect } from "chai"; -import { Realm } from "../index"; +import { Realm } from "../Realm"; describe("platform specifics", () => { describe("default path", () => { diff --git a/packages/realm/src/tests/schema-normalization.test.ts b/packages/realm/src/tests/schema-normalization.test.ts index e873976be7..1778d372c9 100644 --- a/packages/realm/src/tests/schema-normalization.test.ts +++ b/packages/realm/src/tests/schema-normalization.test.ts @@ -19,7 +19,7 @@ import { expect } from "chai"; import { inspect } from "util"; -import { CanonicalPropertySchema, PropertySchema, PropertySchemaShorthand } from "../schema"; +import type { CanonicalPropertySchema, PropertySchema, PropertySchemaShorthand } from "../schema"; import { extractGeneric, normalizePropertySchema } from "../schema/normalize"; import { PropertySchemaParseError } from "../errors"; diff --git a/packages/realm/src/tests/schema-transform.test.ts b/packages/realm/src/tests/schema-transform.test.ts index bcf9f358d4..443d2e11b7 100644 --- a/packages/realm/src/tests/schema-transform.test.ts +++ b/packages/realm/src/tests/schema-transform.test.ts @@ -22,7 +22,7 @@ import { expect } from "chai"; import { fromBindingPropertySchema } from "../schema/from-binding"; import { toBindingPropertySchema } from "../schema/to-binding"; import { normalizePropertySchema } from "../schema/normalize"; -import { PropertySchema } from "../schema/types"; +import type { PropertySchema } from "../schema/types"; const TEST_CASES: (string | PropertySchema)[] = [ "string", diff --git a/packages/realm/src/tests/schema-utils.test.ts b/packages/realm/src/tests/schema-utils.test.ts index 1714c5be9a..0bc13a15cf 100644 --- a/packages/realm/src/tests/schema-utils.test.ts +++ b/packages/realm/src/tests/schema-utils.test.ts @@ -28,7 +28,7 @@ import ColKey = binding.ColKey; import TableKey = binding.TableKey; import TableType = binding.TableType; -import { CanonicalObjectSchema, CanonicalPropertySchema } from "../schema"; +import type { CanonicalObjectSchema, CanonicalPropertySchema } from "../schema"; import { fromBindingObjectSchema, fromBindingPropertySchema } from "../schema/from-binding"; const columnKey = { value: 0n } as unknown as ColKey; diff --git a/packages/realm/src/tests/updateschema.test.ts b/packages/realm/src/tests/updateschema.test.ts index a465feab2a..2308d9d323 100644 --- a/packages/realm/src/tests/updateschema.test.ts +++ b/packages/realm/src/tests/updateschema.test.ts @@ -18,8 +18,9 @@ import { expect } from "chai"; -import { ObjectSchema, Realm } from "../index"; -import { RealmContext, closeRealm, generateTempRealmPath } from "./utils"; +import { Realm } from "../Realm"; +import type { ObjectSchema } from "../schema"; +import { type RealmContext, closeRealm, generateTempRealmPath } from "./utils"; const oldSchema: ObjectSchema[] = [{ name: "Person", properties: { name: "string", age: "int" } }]; const newSchema: ObjectSchema[] = [{ name: "Person2", properties: { title: "string", friends: "int" } }]; diff --git a/packages/realm/src/type-helpers/Array.ts b/packages/realm/src/type-helpers/Array.ts index dcbb381812..cd3d386d42 100644 --- a/packages/realm/src/type-helpers/Array.ts +++ b/packages/realm/src/type-helpers/Array.ts @@ -16,8 +16,10 @@ // //////////////////////////////////////////////////////////////////////////// -import { List, assert, binding } from "../internal"; -import { TypeHelpers, TypeOptions } from "./types"; +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { indirect } from "../indirect"; +import type { TypeHelpers, TypeOptions } from "./types"; /** @internal */ export function createArrayTypeHelpers({ realm, getClassHelpers, name, objectSchemaName }: TypeOptions): TypeHelpers { @@ -30,7 +32,7 @@ export function createArrayTypeHelpers({ realm, getClassHelpers, name, objectSch const propertyHelpers = classHelpers.properties.get(name); const { listAccessor } = propertyHelpers; assert.object(listAccessor); - return new List(realm, value, listAccessor, propertyHelpers); + return new indirect.List(realm, value, listAccessor, propertyHelpers); }, toBinding() { throw new Error("Not supported"); diff --git a/packages/realm/src/type-helpers/Bool.ts b/packages/realm/src/type-helpers/Bool.ts index d006db7e00..7b2ca8a042 100644 --- a/packages/realm/src/type-helpers/Bool.ts +++ b/packages/realm/src/type-helpers/Bool.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import { assert } from "../internal"; +import { assert } from "../assert"; import { defaultFromBinding } from "./default"; import { nullPassthrough } from "./null-passthrough"; import type { TypeHelpers, TypeOptions } from "./types"; diff --git a/packages/realm/src/type-helpers/Data.ts b/packages/realm/src/type-helpers/Data.ts index 10cfc10ba4..76af81381b 100644 --- a/packages/realm/src/type-helpers/Data.ts +++ b/packages/realm/src/type-helpers/Data.ts @@ -18,8 +18,8 @@ import { defaultFromBinding } from "./default"; import { nullPassthrough } from "./null-passthrough"; -import { TypeHelpers, TypeOptions } from "./types"; import { toArrayBuffer } from "./array-buffer"; +import type { TypeHelpers, TypeOptions } from "./types"; /** @internal */ export function createDataTypeHelpers({ optional }: TypeOptions): TypeHelpers { diff --git a/packages/realm/src/type-helpers/Date.ts b/packages/realm/src/type-helpers/Date.ts index f63f507ac7..2a5e972997 100644 --- a/packages/realm/src/type-helpers/Date.ts +++ b/packages/realm/src/type-helpers/Date.ts @@ -16,9 +16,10 @@ // //////////////////////////////////////////////////////////////////////////// -import { assert, binding } from "../internal"; +import { binding } from "../../binding"; +import { assert } from "../assert"; import { nullPassthrough } from "./null-passthrough"; -import { TypeOptions } from "./types"; +import type { TypeOptions } from "./types"; /** @internal */ export function createDateTypeHelpers({ optional }: TypeOptions) { diff --git a/packages/realm/src/type-helpers/Decimal.ts b/packages/realm/src/type-helpers/Decimal.ts index ddf1f1b8f1..06d67e66b2 100644 --- a/packages/realm/src/type-helpers/Decimal.ts +++ b/packages/realm/src/type-helpers/Decimal.ts @@ -16,10 +16,11 @@ // //////////////////////////////////////////////////////////////////////////// -import { BSON, assert } from "../internal"; +import { assert } from "../assert"; +import { BSON } from "../bson"; import { defaultFromBinding } from "./default"; import { nullPassthrough } from "./null-passthrough"; -import { TypeHelpers, TypeOptions } from "./types"; +import type { TypeHelpers, TypeOptions } from "./types"; /** @internal */ export function createDecimalTypeHelpers({ optional }: TypeOptions): TypeHelpers { diff --git a/packages/realm/src/type-helpers/Double.ts b/packages/realm/src/type-helpers/Double.ts index 74bd49c8ff..1e79e0a397 100644 --- a/packages/realm/src/type-helpers/Double.ts +++ b/packages/realm/src/type-helpers/Double.ts @@ -16,10 +16,10 @@ // //////////////////////////////////////////////////////////////////////////// -import { assert } from "../internal"; +import { assert } from "../assert"; import { defaultFromBinding } from "./default"; import { nullPassthrough } from "./null-passthrough"; -import { TypeHelpers, TypeOptions } from "./types"; +import type { TypeHelpers, TypeOptions } from "./types"; /** @internal */ export function createDoubleTypeHelpers({ optional }: TypeOptions): TypeHelpers { diff --git a/packages/realm/src/type-helpers/Float.ts b/packages/realm/src/type-helpers/Float.ts index 1b627ad239..ebcaac14a0 100644 --- a/packages/realm/src/type-helpers/Float.ts +++ b/packages/realm/src/type-helpers/Float.ts @@ -16,9 +16,10 @@ // //////////////////////////////////////////////////////////////////////////// -import { assert, binding } from "../internal"; +import { binding } from "../../binding"; +import { assert } from "../assert"; import { nullPassthrough } from "./null-passthrough"; -import { TypeHelpers, TypeOptions } from "./types"; +import type { TypeHelpers, TypeOptions } from "./types"; /** @internal */ export function createFloatTypeHelpers({ optional }: TypeOptions): TypeHelpers { diff --git a/packages/realm/src/type-helpers/Int.ts b/packages/realm/src/type-helpers/Int.ts index 6a35b0a825..757aebf1ba 100644 --- a/packages/realm/src/type-helpers/Int.ts +++ b/packages/realm/src/type-helpers/Int.ts @@ -16,7 +16,9 @@ // //////////////////////////////////////////////////////////////////////////// -import { Counter, TypeAssertionError, binding } from "../internal"; +import { binding } from "../../binding"; +import { TypeAssertionError } from "../errors"; +import { Counter } from "../Counter"; import { nullPassthrough } from "./null-passthrough"; import type { TypeHelpers, TypeOptions } from "./types"; diff --git a/packages/realm/src/type-helpers/LinkingObjects.ts b/packages/realm/src/type-helpers/LinkingObjects.ts index 1874a5a935..f39035f16c 100644 --- a/packages/realm/src/type-helpers/LinkingObjects.ts +++ b/packages/realm/src/type-helpers/LinkingObjects.ts @@ -16,9 +16,10 @@ // //////////////////////////////////////////////////////////////////////////// -import { assert, binding } from "../internal"; +import { binding } from "../../binding"; +import { assert } from "../assert"; import { defaultToBinding } from "./default"; -import { TypeHelpers, TypeOptions } from "./types"; +import type { TypeHelpers, TypeOptions } from "./types"; /** @internal */ export function createLinkingObjectsTypeHelpers({ objectType, getClassHelpers }: TypeOptions): TypeHelpers { diff --git a/packages/realm/src/type-helpers/Mixed.ts b/packages/realm/src/type-helpers/Mixed.ts index bb4341e83c..7d46072e6d 100644 --- a/packages/realm/src/type-helpers/Mixed.ts +++ b/packages/realm/src/type-helpers/Mixed.ts @@ -16,29 +16,24 @@ // //////////////////////////////////////////////////////////////////////////// +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { indirect } from "../indirect"; +import { createDictionaryAccessor } from "../collection-accessors/Dictionary"; +import { createListAccessor } from "../collection-accessors/List"; import { - Collection, - Counter, - Dictionary, - INTERNAL, - List, - REALM, - RealmObject, - RealmSet, - assert, - binding, boxToBindingGeospatial, circleToBindingGeospatial, - createDictionaryAccessor, - createListAccessor, - getTypeHelpers, isGeoBox, isGeoCircle, isGeoPolygon, polygonToBindingGeospatial, -} from "../internal"; +} from "../GeoSpatial"; +import { Counter } from "../Counter"; +import { getTypeHelpers } from "../TypeHelpers"; +import { OBJECT_INTERNAL, OBJECT_REALM } from "../symbols"; import { TYPED_ARRAY_CONSTRUCTORS } from "./array-buffer"; -import { TypeHelpers, TypeOptions } from "./types"; +import type { TypeHelpers, TypeOptions } from "./types"; // TODO: Consider testing for expected object instance types and throw something similar to the legacy SDK: // "Only Realm instances are supported." (which should probably have been "RealmObject") @@ -66,14 +61,14 @@ export function mixedToBinding( return null; } else if (value instanceof Date) { return binding.Timestamp.fromDate(value); - } else if (value instanceof RealmObject) { + } else if (value instanceof indirect.Object) { if (value.objectSchema().embedded) { throw new Error(`Using an embedded object (${value.constructor.name}) as ${displayedType} is not supported.`); } - const otherRealm = value[REALM].internal; + const otherRealm = value[OBJECT_REALM].internal; assert.isSameRealm(realm, otherRealm, "Realm object is from another Realm"); - return value[INTERNAL]; - } else if (value instanceof RealmSet || value instanceof Set) { + return value[OBJECT_INTERNAL]; + } else if (value instanceof indirect.Set || value instanceof Set) { throw new Error(`Using a ${value.constructor.name} as ${displayedType} is not supported.`); } else if (value instanceof Counter) { let errMessage = `Using a Counter as ${displayedType} is not supported.`; @@ -81,7 +76,7 @@ export function mixedToBinding( throw new Error(errMessage); } else { if (isQueryArg) { - if (value instanceof Collection || Array.isArray(value)) { + if (value instanceof indirect.Collection || Array.isArray(value)) { throw new Error(`Using a ${value.constructor.name} as a query argument is not supported.`); } // Geospatial types can currently only be used when querying and @@ -126,11 +121,16 @@ function mixedFromBinding(options: TypeOptions, value: binding.MixedArg): unknow } else if (value instanceof binding.List) { const mixedType = binding.PropertyType.Mixed; const typeHelpers = getTypeHelpers(mixedType, options); - return new List(realm, value, createListAccessor({ realm, typeHelpers, itemType: mixedType }), typeHelpers); + return new indirect.List( + realm, + value, + createListAccessor({ realm, typeHelpers, itemType: mixedType }), + typeHelpers, + ); } else if (value instanceof binding.Dictionary) { const mixedType = binding.PropertyType.Mixed; const typeHelpers = getTypeHelpers(mixedType, options); - return new Dictionary( + return new indirect.Dictionary( realm, value, createDictionaryAccessor({ realm, typeHelpers, itemType: mixedType }), diff --git a/packages/realm/src/type-helpers/Object.ts b/packages/realm/src/type-helpers/Object.ts index 122fae5a3a..b975ec2e5d 100644 --- a/packages/realm/src/type-helpers/Object.ts +++ b/packages/realm/src/type-helpers/Object.ts @@ -16,9 +16,12 @@ // //////////////////////////////////////////////////////////////////////////// -import { INTERNAL, REALM, RealmObject, UpdateMode, assert, binding } from "../internal"; +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { RealmObject, UpdateMode } from "../Object"; +import { OBJECT_INTERNAL, OBJECT_REALM } from "../symbols"; import { nullPassthrough } from "./null-passthrough"; -import { TypeHelpers, TypeOptions } from "./types"; +import type { TypeHelpers, TypeOptions } from "./types"; /** @internal */ export function createObjectTypeHelpers({ @@ -36,9 +39,9 @@ export function createObjectTypeHelpers({ if ( value instanceof RealmObject && value.constructor.name === objectType && - value[REALM].internal.$addr === realm.internal.$addr + value[OBJECT_REALM].internal.$addr === realm.internal.$addr ) { - return value[INTERNAL]; + return value[OBJECT_INTERNAL]; } else { // TODO: Consider exposing a way for calling code to disable object creation assert.object(value, name); @@ -49,7 +52,7 @@ export function createObjectTypeHelpers({ helpers, createObj: options?.createObj, }); - return createdObject[INTERNAL]; + return createdObject[OBJECT_INTERNAL]; } }, optional), fromBinding: nullPassthrough((value) => { diff --git a/packages/realm/src/type-helpers/ObjectId.ts b/packages/realm/src/type-helpers/ObjectId.ts index 2d285c148e..7b7d425aa7 100644 --- a/packages/realm/src/type-helpers/ObjectId.ts +++ b/packages/realm/src/type-helpers/ObjectId.ts @@ -16,10 +16,11 @@ // //////////////////////////////////////////////////////////////////////////// +import { assert } from "../assert"; +import { BSON } from "../bson"; import { defaultFromBinding } from "./default"; import { nullPassthrough } from "./null-passthrough"; -import { TypeHelpers, TypeOptions } from "./types"; -import { BSON, assert } from "../internal"; +import type { TypeHelpers, TypeOptions } from "./types"; /** @internal */ export function createObjectIdTypeHelpers({ optional }: TypeOptions): TypeHelpers { diff --git a/packages/realm/src/type-helpers/String.ts b/packages/realm/src/type-helpers/String.ts index 022dcbd2b4..95f6929a76 100644 --- a/packages/realm/src/type-helpers/String.ts +++ b/packages/realm/src/type-helpers/String.ts @@ -16,10 +16,10 @@ // //////////////////////////////////////////////////////////////////////////// -import { assert } from "../internal"; +import { assert } from "../assert"; import { defaultFromBinding } from "./default"; import { nullPassthrough } from "./null-passthrough"; -import { TypeHelpers, TypeOptions } from "./types"; +import type { TypeHelpers, TypeOptions } from "./types"; /** @internal */ export function createStringTypeHelpers({ optional }: TypeOptions): TypeHelpers { diff --git a/packages/realm/src/type-helpers/Uuid.ts b/packages/realm/src/type-helpers/Uuid.ts index 10e3ecfbda..95cee3848a 100644 --- a/packages/realm/src/type-helpers/Uuid.ts +++ b/packages/realm/src/type-helpers/Uuid.ts @@ -16,10 +16,11 @@ // //////////////////////////////////////////////////////////////////////////// -import { BSON, assert } from "../internal"; +import { assert } from "../assert"; +import { BSON } from "../bson"; import { defaultFromBinding } from "./default"; import { nullPassthrough } from "./null-passthrough"; -import { TypeHelpers, TypeOptions } from "./types"; +import type { TypeHelpers, TypeOptions } from "./types"; /** @internal */ export function createUuidTypeHelpers({ optional }: TypeOptions): TypeHelpers { diff --git a/packages/realm/src/type-helpers/array-buffer.ts b/packages/realm/src/type-helpers/array-buffer.ts index 0acf36baf0..254a81aca5 100644 --- a/packages/realm/src/type-helpers/array-buffer.ts +++ b/packages/realm/src/type-helpers/array-buffer.ts @@ -16,7 +16,9 @@ // //////////////////////////////////////////////////////////////////////////// -import { assert, binding, safeGlobalThis } from "../internal"; +import { binding } from "../../binding"; +import { assert } from "../assert"; +import { safeGlobalThis } from "../safeGlobalThis"; /** @internal */ export const TYPED_ARRAY_CONSTRUCTORS = new Set( diff --git a/packages/realm/src/type-helpers/default.ts b/packages/realm/src/type-helpers/default.ts index 60d77824e5..a6e10b2958 100644 --- a/packages/realm/src/type-helpers/default.ts +++ b/packages/realm/src/type-helpers/default.ts @@ -16,7 +16,7 @@ // //////////////////////////////////////////////////////////////////////////// -import type { binding } from "../internal"; +import type { binding } from "../../binding"; /** @internal */ export function defaultToBinding(value: unknown): binding.MixedArg { diff --git a/packages/realm/src/type-helpers/types.ts b/packages/realm/src/type-helpers/types.ts index b1a5923733..bf27eaeeb4 100644 --- a/packages/realm/src/type-helpers/types.ts +++ b/packages/realm/src/type-helpers/types.ts @@ -16,7 +16,11 @@ // //////////////////////////////////////////////////////////////////////////// -import type { ClassHelpers, ObjCreator, PresentationPropertyTypeName, Realm, UpdateMode, binding } from "../internal"; +import type { binding } from "../../binding"; +import type { ClassHelpers } from "../ClassHelpers"; +import type { PresentationPropertyTypeName } from "../schema"; +import type { ObjCreator, UpdateMode } from "../Object"; +import type { Realm } from "../Realm"; /** @internal */ export type TypeHelpers = {