@pomwik/afterdb-react 0.0.0-stage → 0.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGES-FROM-UPSTREAM.md +59 -0
  2. package/LICENSE +177 -0
  3. package/NOTICE +9 -0
  4. package/README.md +10 -2
  5. package/dist/RealmContext.d.ts +153 -0
  6. package/dist/RealmContext.d.ts.map +1 -0
  7. package/dist/RealmProvider.d.ts +95 -0
  8. package/dist/RealmProvider.d.ts.map +1 -0
  9. package/dist/cachedCollection.d.ts +58 -0
  10. package/dist/cachedCollection.d.ts.map +1 -0
  11. package/dist/cachedObject.d.ts +48 -0
  12. package/dist/cachedObject.d.ts.map +1 -0
  13. package/dist/helpers.d.ts +22 -0
  14. package/dist/helpers.d.ts.map +1 -0
  15. package/dist/index.cjs +2818 -0
  16. package/dist/index.cjs.map +1 -0
  17. package/dist/index.d.ts +100 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +2809 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/tsconfig.types.tsbuildinfo +1 -0
  22. package/dist/types.d.ts +64 -0
  23. package/dist/types.d.ts.map +1 -0
  24. package/dist/useObject.d.ts +30 -0
  25. package/dist/useObject.d.ts.map +1 -0
  26. package/dist/useQuery.d.ts +31 -0
  27. package/dist/useQuery.d.ts.map +1 -0
  28. package/dist/useRealm.d.ts +12 -0
  29. package/dist/useRealm.d.ts.map +1 -0
  30. package/package.json +117 -4
  31. package/src/RealmContext.ts +196 -0
  32. package/src/RealmProvider.tsx +251 -0
  33. package/src/__tests__/RealmProvider.test.tsx +583 -0
  34. package/src/__tests__/createRealmTestContext.ts +68 -0
  35. package/src/__tests__/helpers.ts +35 -0
  36. package/src/__tests__/mocks.ts +154 -0
  37. package/src/__tests__/profileHook.tsx +76 -0
  38. package/src/__tests__/setup.ts +22 -0
  39. package/src/__tests__/tsconfig.json +14 -0
  40. package/src/__tests__/useObjectHook.test.tsx +158 -0
  41. package/src/__tests__/useObjectRender.test.tsx +630 -0
  42. package/src/__tests__/useQueryHook.test.tsx +209 -0
  43. package/src/__tests__/useQueryRender.test.tsx +463 -0
  44. package/src/cachedCollection.ts +210 -0
  45. package/src/cachedObject.ts +164 -0
  46. package/src/helpers.ts +60 -0
  47. package/src/index.tsx +130 -0
  48. package/src/runtime.d.ts +31 -0
  49. package/src/types.ts +92 -0
  50. package/src/useObject.tsx +227 -0
  51. package/src/useQuery.tsx +205 -0
  52. package/src/useRealm.tsx +41 -0
@@ -0,0 +1,210 @@
1
+ ////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // Copyright 2022 Realm Inc.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ //
17
+ ////////////////////////////////////////////////////////////////////////////
18
+
19
+ import Realm from "realm";
20
+
21
+ import { CollectionCallback } from "./helpers";
22
+
23
+ const numericRegEx = /^-?\d+$/;
24
+
25
+ function getCacheKey(id: string) {
26
+ return `${id}`;
27
+ }
28
+
29
+ /**
30
+ * Arguments object for {@link createCachedCollection}.
31
+ */
32
+ type CachedCollectionArgs<T> = {
33
+ /**
34
+ * The {@link Realm.Collection} to proxy
35
+ */
36
+ collection: Realm.List<T> | Realm.Results<T>;
37
+
38
+ /**
39
+ * The {@link Realm} instance
40
+ */
41
+ realm: Realm;
42
+
43
+ /**
44
+ * Callback which is called whenever an object in the collection changes
45
+ */
46
+ updateCallback: () => void;
47
+
48
+ /**
49
+ * Reference boolean which is set to true whenever an object in the collection changes
50
+ * It is used to determine if the collection's object reference should be updated
51
+ * The implementing component should reset this to false when updating its object reference
52
+ */
53
+ updatedRef: React.MutableRefObject<boolean>;
54
+
55
+ /**
56
+ * Optional Map to be used as the cache. This is used to allow a `sorted` or `filtered`
57
+ * (derived) version of the collection to reuse the same cache, preventing excess new object
58
+ * references being created.
59
+ */
60
+ objectCache?: Map<string, T>;
61
+
62
+ /**
63
+ * Optional flag specifying that this is a derived (`sorted` or `filtered`) version of
64
+ * an existing collection, so we should not create or remove listeners or clear the cache
65
+ * when this is torn down.
66
+ */
67
+ isDerived?: boolean;
68
+
69
+ /**
70
+ * Optional list of key-paths to limit notifications.
71
+ */
72
+ keyPaths?: string[];
73
+ };
74
+
75
+ /**
76
+ * Creates a proxy around a {@link Realm.Collection} that will create new {@link Realm.Object}
77
+ * references on any relevant change (update, insert, deletion) and return the same
78
+ * object reference if no changes have occurred since the last access.
79
+ *
80
+ * This makes the {@link Realm.Collection} behaves in an immutable way, as React expects, so
81
+ * that a {@link Realm.Object} can be wrapped in {@link React.memo} to prevent unnecessary
82
+ * rendering (see {@link useQuery} hook).
83
+ * @param args {@link CachedCollectionArgs} object arguments
84
+ * @returns Proxy object wrapping the collection
85
+ */
86
+ export function createCachedCollection<T extends Realm.Object<any>>({
87
+ collection,
88
+ realm,
89
+ updateCallback,
90
+ updatedRef,
91
+ objectCache = new Map(),
92
+ isDerived = false,
93
+ keyPaths,
94
+ }: CachedCollectionArgs<T>): { collection: Realm.Results<T> | Realm.List<T>; tearDown: () => void } {
95
+ const cachedCollectionHandler: ProxyHandler<Realm.Results<T> | Realm.List<T>> = {
96
+ get: function (target, key, receiver) {
97
+ // Pass functions through
98
+ const value = Reflect.get(target, key, receiver);
99
+ if (typeof value === "function") {
100
+ if (key === "sorted" || key === "filtered") {
101
+ return (...args: unknown[]) => {
102
+ const col: Realm.Results<T & Realm.Object> = Reflect.apply(value, target, args);
103
+ const { collection: newCol } = createCachedCollection({
104
+ collection: col,
105
+ realm,
106
+ updateCallback,
107
+ updatedRef,
108
+ objectCache,
109
+ isDerived: true,
110
+ keyPaths,
111
+ });
112
+ return newCol;
113
+ };
114
+ }
115
+ return value;
116
+ }
117
+
118
+ // If the key is not numeric, pass it through
119
+ if (typeof key === "symbol" || !numericRegEx.test(key)) {
120
+ return value;
121
+ }
122
+
123
+ // If the key is numeric, check if we have a cached object for this key
124
+ const index = Number(key);
125
+ const object = target[index];
126
+
127
+ // If the collection is modeled in a way that objects can be null
128
+ // then we should return null instead of undefined to stay semantically
129
+ // correct
130
+ if (object === null) {
131
+ return null;
132
+ } else if (typeof object === "undefined") {
133
+ // If there is no object at this index, return undefined
134
+ return undefined;
135
+ }
136
+
137
+ const objectId = object._objectKey();
138
+ const cacheKey = getCacheKey(objectId);
139
+
140
+ // If we do, return it...
141
+ if (objectCache.get(cacheKey)) {
142
+ return objectCache.get(cacheKey);
143
+ }
144
+
145
+ // If not then this index has either not been accessed before, or has been invalidated due
146
+ // to a modification. Fetch it from the collection and store it in the cache
147
+ objectCache.set(cacheKey, object);
148
+
149
+ return object;
150
+ },
151
+ };
152
+
153
+ const cachedCollectionResult = new Proxy(collection, cachedCollectionHandler);
154
+
155
+ const listenerCallback: CollectionCallback = (listenerCollection, changes) => {
156
+ if (changes.deletions.length > 0 || changes.insertions.length > 0 || changes.newModifications.length > 0) {
157
+ // TODO: There is currently no way to rebuild the cache key from the changes array for deleted object.
158
+ // Until it is possible, we clear the cache on deletions.
159
+ // Blocking issue: https://github.com/realm/realm-core/issues/5220
160
+
161
+ // Possible solutions:
162
+ // a. the listenerCollection is a frozen copy of the collection before the deletion,
163
+ // allowing accessing the _objectKey() using listenerCollection[index]._objectKey()
164
+ // b. the callback provides an array of changed objectIds
165
+
166
+ if (changes.deletions.length > 0) {
167
+ objectCache.clear();
168
+ }
169
+
170
+ // Item(s) were modified, just clear them from the cache so that we return new instances for them
171
+ changes.newModifications.forEach((index) => {
172
+ const objectId = listenerCollection[index]._objectKey();
173
+ if (objectId) {
174
+ const cacheKey = getCacheKey(objectId);
175
+ if (objectCache.has(cacheKey)) {
176
+ objectCache.delete(cacheKey);
177
+ }
178
+ }
179
+ });
180
+ updatedRef.current = true;
181
+ updateCallback();
182
+ }
183
+ };
184
+
185
+ let setImmediateId: ReturnType<typeof setImmediate> | undefined = undefined;
186
+ if (!isDerived) {
187
+ // If we are in a transaction, then push adding the listener to the event loop. This will allow the write transaction to finish.
188
+ // see https://github.com/realm/realm-js/issues/4375
189
+ if (realm.isInTransaction) {
190
+ setImmediateId = setImmediate(() => {
191
+ collection.addListener(listenerCallback, keyPaths);
192
+ });
193
+ } else {
194
+ collection.addListener(listenerCallback, keyPaths);
195
+ }
196
+ }
197
+
198
+ const tearDown = () => {
199
+ if (!isDerived) {
200
+ if (setImmediateId) {
201
+ clearImmediate(setImmediateId);
202
+ setImmediateId = undefined;
203
+ }
204
+ collection.removeListener(listenerCallback);
205
+ objectCache.clear();
206
+ }
207
+ };
208
+
209
+ return { collection: cachedCollectionResult, tearDown };
210
+ }
@@ -0,0 +1,164 @@
1
+ ////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // Copyright 2022 Realm Inc.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ //
17
+ ////////////////////////////////////////////////////////////////////////////
18
+
19
+ import Realm from "realm";
20
+
21
+ import { createCachedCollection } from "./cachedCollection";
22
+
23
+ /**
24
+ * Arguments object for `cachedObject`.
25
+ */
26
+ type CachedObjectArgs = {
27
+ /**
28
+ * The {@link Realm.Object} to proxy
29
+ */
30
+ object: Realm.Object | null;
31
+ /**
32
+ * The {@link Realm} instance
33
+ */
34
+ realm: Realm;
35
+ /**
36
+ * Callback function called whenver the object changes. Used to force a component
37
+ * using the {@link useObject} hook to re-render.
38
+ */
39
+ updateCallback: () => void;
40
+
41
+ /**
42
+ * Reference boolean which is set to true whenever the object changes
43
+ * It is used to determine if the object's reference should be updated
44
+ * The implementing component should reset this to false when updating its object reference
45
+ */
46
+ updatedRef: React.MutableRefObject<boolean>;
47
+
48
+ /**
49
+ * Optional list of key-paths to limit notifications.
50
+ */
51
+ keyPaths?: string[];
52
+ };
53
+
54
+ export type CachedObject = {
55
+ object: Realm.Object | null;
56
+ tearDown: () => void;
57
+ };
58
+
59
+ /**
60
+ * Creates a proxy around a {@link Realm.Object} that will return a new reference
61
+ * on any relevant update to the object itself. It also wraps accesses to {@link Realm.List}
62
+ * attributes into a {@link cachedCollection}, so that any update, insert or deletion to the
63
+ * list will also return a new object reference.
64
+ *
65
+ * See {@link cachedCollection} and the `useObject` hook for description of how this
66
+ * helps prevent unnecessary rendering.
67
+ * @param args - {@link CachedObjectArgs} object arguments
68
+ * @returns Proxy object wrapping the {@link Realm.Object}
69
+ */
70
+ export function createCachedObject({
71
+ object,
72
+ realm,
73
+ updateCallback,
74
+ updatedRef,
75
+ keyPaths,
76
+ }: CachedObjectArgs): CachedObject {
77
+ const listCaches = new Map();
78
+ const listTearDowns: Array<() => void> = [];
79
+ // If the object doesn't exist, just return it with an noop tearDown
80
+ //
81
+ if (object === null) {
82
+ return { object, tearDown: () => undefined };
83
+ }
84
+
85
+ // Create a cache for any Realm.List properties on the object
86
+ for (const key of object.keys()) {
87
+ //@ts-expect-error - TS doesn't know that the key is a valid property
88
+ const value = object[key];
89
+ if (value instanceof Realm.List && value.type === "object") {
90
+ const updatedRef = { current: true };
91
+ const { collection, tearDown } = createCachedCollection({ collection: value, realm, updateCallback, updatedRef });
92
+ listCaches.set(key, { collection, updatedRef });
93
+ listTearDowns.push(tearDown);
94
+ }
95
+ }
96
+
97
+ // This Proxy handler intercepts any accesses into properties of the cached object
98
+ // of type `Realm.List`, and returns a `cachedCollection` wrapping those properties
99
+ // to allow changes in the list to trigger re-renders
100
+ const cachedObjectHandler: ProxyHandler<Realm.Object> = {
101
+ get: function (target, key, receiver) {
102
+ const value = Reflect.get(target, key, receiver);
103
+
104
+ // If its a Realm.List we need to add a proxy cache around it
105
+ if (value instanceof Realm.List && value.type === "object") {
106
+ if (listCaches.has(key)) {
107
+ // Return a new proxy wrapping the cachedCollection so that its reference gets updated,
108
+ // otherwise the list component will not re-render. The cachedCollection then ensures that
109
+ // only the modified children of the list component actually re-render.
110
+ const { collection, updatedRef } = listCaches.get(key);
111
+ if (updatedRef.current) {
112
+ updatedRef.current = false;
113
+ const proxyCollection = new Proxy(collection, {});
114
+ listCaches.set(key, { collection: proxyCollection, updatedRef });
115
+ return proxyCollection;
116
+ }
117
+ return collection;
118
+ }
119
+ }
120
+ return value;
121
+ },
122
+ };
123
+
124
+ const cachedObjectResult = new Proxy(object, cachedObjectHandler);
125
+ const listenerCallback: Realm.ObjectChangeCallback<any> = (obj, changes) => {
126
+ updatedRef.current = true;
127
+ if (changes.deleted) {
128
+ updateCallback();
129
+ } else if (changes.changedProperties.length > 0) {
130
+ // Don't force a second re-render if any of the changed properties is a Realm.List,
131
+ // as the List's cachedCollection will force a re-render itself
132
+ const anyListPropertyModified = changes.changedProperties.some((property) => {
133
+ return obj[property] instanceof Realm.List && obj[property].type === "object";
134
+ });
135
+ const shouldRerender = !anyListPropertyModified;
136
+
137
+ if (shouldRerender) {
138
+ updateCallback();
139
+ }
140
+ }
141
+ };
142
+
143
+ // We cannot add a listener to an invalid object
144
+ if (object.isValid()) {
145
+ // If we are in a transaction, then push adding the listener to the event loop. This will allow the write transaction to finish.
146
+ // see https://github.com/realm/realm-js/issues/4375
147
+ if (realm.isInTransaction) {
148
+ setImmediate(() => {
149
+ object.addListener(listenerCallback, keyPaths);
150
+ });
151
+ } else {
152
+ object.addListener(listenerCallback, keyPaths);
153
+ }
154
+ }
155
+
156
+ const tearDown = () => {
157
+ object.removeListener(listenerCallback);
158
+ for (const listTearDown of listTearDowns) {
159
+ listTearDown();
160
+ }
161
+ };
162
+
163
+ return { object: cachedObjectResult, tearDown };
164
+ }
package/src/helpers.ts ADDED
@@ -0,0 +1,60 @@
1
+ ////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // Copyright 2023 Realm Inc.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ //
17
+ ////////////////////////////////////////////////////////////////////////////
18
+
19
+ import Realm from "realm";
20
+
21
+ // Convenience function that returns the correct type for the objectForPrimaryKey function
22
+ // Since we don't have a combined declaration for this function, typescript needs to know
23
+ // which return to use based on the typeof the type argument
24
+ export function getObjectForPrimaryKey<T extends Realm.Object>(
25
+ realm: Realm,
26
+ type: string | { new (...args: any): T },
27
+ primaryKey: T[keyof T],
28
+ ) {
29
+ return typeof type === "string"
30
+ ? realm.objectForPrimaryKey(type, primaryKey)
31
+ : realm.objectForPrimaryKey(type, primaryKey);
32
+ }
33
+
34
+ // Convenience function that returns the correct type for the objects function
35
+ // Since we don't have a combined declaration for this function, typescript needs to know
36
+ // which return to use based on the typeof the type argument
37
+ export function getObjects<T extends Realm.Object>(
38
+ realm: Realm,
39
+ type: string | { new (...args: any): T },
40
+ ): Realm.Results<T> {
41
+ return (typeof type === "string" ? realm.objects(type) : realm.objects(type)) as Realm.Results<T>;
42
+ }
43
+
44
+ export type CollectionCallback = Parameters<typeof Realm.Results.prototype.addListener>[0];
45
+
46
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
47
+ export type AnyRealmObject = Realm.Object<any>;
48
+
49
+ export type RealmClassType<T = any> = { new (...args: any): T };
50
+
51
+ /**
52
+ * Explicitly sets the unpicked properties of a type to never instead of dropping them like in Pick.
53
+ * Useful for ensuring different prop types are mutually exclusive as React expects the union type
54
+ * of different prop types to include all the fields.
55
+ */
56
+ export type RestrictivePick<T, K extends keyof T> = Pick<T, K> & { [RestrictedKey in keyof Omit<T, K>]?: never };
57
+
58
+ export function isClassModelConstructor(value: unknown): value is RealmClassType<unknown> {
59
+ return Object.getPrototypeOf(value) === Realm.Object;
60
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,130 @@
1
+ ////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // Copyright 2021 Realm Inc.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ //
17
+ ////////////////////////////////////////////////////////////////////////////
18
+
19
+ import Realm from "realm";
20
+ import React from "react";
21
+ import { createRealmContext } from "./RealmContext";
22
+
23
+ export type { UseObjectHook } from "./useObject";
24
+ export type { UseQueryHook, QueryHookOptions } from "./useQuery";
25
+
26
+ const defaultContext = createRealmContext();
27
+
28
+ /**
29
+ * The Provider component that is required to wrap any component using
30
+ * the Realm hooks.
31
+ * @example
32
+ * ```
33
+ * const AppRoot = () => {
34
+ * const syncConfig = {
35
+ * flexible: true,
36
+ * user: currentUser
37
+ * };
38
+ *
39
+ * return (
40
+ * <RealmProvider schema={[Task, User]} path={"data.realm"} sync={syncConfig}>
41
+ * <App/>
42
+ * </RealmProvider>
43
+ * )
44
+ * }
45
+ * ```
46
+ * @example
47
+ * const syncConfig = {
48
+ * flexible: true,
49
+ * user: currentUser
50
+ * };
51
+ * const realm = new Realm(schema:[Task, User], path:"data.realm", sync: syncConfig);
52
+ * ...
53
+ * const AppRoot = () => {
54
+ * return (
55
+ * <RealmProvider>
56
+ * <App/>
57
+ * </RealmProvider>
58
+ * )
59
+ * }
60
+ * @param props - The {@link Realm.Configuration} or {@link Realm} for this Provider, passed as props.
61
+ */
62
+ export const RealmProvider = defaultContext.RealmProvider;
63
+
64
+ /**
65
+ * Returns the instance of the {@link Realm} opened by the `RealmProvider`.
66
+ * @example
67
+ * ```
68
+ * const realm = useRealm();
69
+ * ```
70
+ * @returns a realm instance
71
+ */
72
+ export const useRealm = defaultContext.useRealm;
73
+
74
+ /**
75
+ * Returns a {@link Realm.Collection} of {@link Realm.Object}s from a given type.
76
+ * The hook will update on any changes to any object in the collection.
77
+ *
78
+ * The result of this can be consumed directly by the `data` argument of any React Native
79
+ * VirtualizedList or FlatList. If the component used for the list's `renderItem` prop is {@link React.Memo}ized,
80
+ * then only the modified object will re-render.
81
+ * @example
82
+ * ```tsx
83
+ * // Return all collection items
84
+ * const collection = useQuery({ type: Object });
85
+ *
86
+ * // Return all collection items sorted by name and filtered by category
87
+ * const filteredAndSorted = useQuery({
88
+ * type: Object,
89
+ * query: (collection) => collection.filtered('category == $0',category).sorted('name'),
90
+ * }, [category]);
91
+ *
92
+ * // Return all collection items sorted by name and filtered by category, triggering re-renders only if "name" changes
93
+ * const filteredAndSorted = useQuery({
94
+ * type: Object,
95
+ * query: (collection) => collection.filtered('category == $0',category).sorted('name'),
96
+ * keyPaths: ["name"]
97
+ * }, [category]);
98
+ * ```
99
+ * @param options
100
+ * @param options.type - The object type, depicted by a string or a class extending Realm.Object
101
+ * @param options.query - A function that takes a {@link Realm.Collection} and returns a {@link Realm.Collection} of the same type. This allows for filtering and sorting of the collection, before it is returned.
102
+ * @param options.keyPaths - Indicates a lower bound on the changes relevant for the hook. This is a lower bound, since if multiple hooks add listeners (each with their own `keyPaths`) the union of these key-paths will determine the changes that are considered relevant for all listeners registered on the collection. In other words: A listener might fire and cause a re-render more than the key-paths specify, if other listeners with different key-paths are present.
103
+ * @param deps - An array of dependencies that will be passed to {@link React.useMemo}
104
+ * @returns a collection of realm objects or an empty array
105
+ */
106
+ export const useQuery = defaultContext.useQuery;
107
+
108
+ /**
109
+ * Returns a {@link Realm.Object} from a given type and value of primary key.
110
+ * The hook will update on any changes to the properties on the returned object
111
+ * and return null if it either doesn't exists or has been deleted.
112
+ * @example
113
+ * ```
114
+ * const object = useObject(ObjectClass, objectId);
115
+ * ```
116
+ * @param type - The object type, depicted by a string or a class extending {@link Realm.Object}
117
+ * @param primaryKey - The primary key of the desired object which will be retrieved using {@link Realm.objectForPrimaryKey}
118
+ * @param keyPaths - Indicates a lower bound on the changes relevant for the hook. This is a lower bound, since if multiple hooks add listeners (each with their own `keyPaths`) the union of these key-paths will determine the changes that are considered relevant for all listeners registered on the object. In other words: A listener might fire and cause a re-render more than the key-paths specify, if other listeners with different key-paths are present.
119
+ * @returns either the desired {@link Realm.Object} or `null` in the case of it being deleted or not existing.
120
+ */
121
+ export const useObject = defaultContext.useObject;
122
+
123
+ /*
124
+ * @ignore This will end up documenting all of Realm, which is documented elsewhere
125
+ */
126
+ export { Realm };
127
+ export { createRealmContext } from "./RealmContext";
128
+ export * from "./types";
129
+ export { createUseObject } from "./useObject";
130
+ export { createUseQuery } from "./useQuery";
@@ -0,0 +1,31 @@
1
+ ////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ // Copyright 2024 Realm Inc.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ //
17
+ ////////////////////////////////////////////////////////////////////////////
18
+
19
+ declare type Console = {
20
+ log(...args: unknown[]): void;
21
+ error(...args: unknown[]): void;
22
+ warn(...args: unknown[]): void;
23
+ };
24
+
25
+ declare const console: Console;
26
+
27
+ declare function setImmediate(cb: (...args: unknown[]) => void);
28
+
29
+ declare type Timer = unknown;
30
+ declare function clearImmediate(timer: Timer): void;
31
+