Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Onyx Connection Manager #567

Merged
merged 36 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
fb66f0b
Improve connect typings
fabioh8010 Jun 8, 2024
65edb35
Implement first version of OnyxConnectionManager
fabioh8010 Jun 11, 2024
8db2eed
Add value support to connection manager callback and tests
fabioh8010 Jul 1, 2024
24f7512
Merge branch 'main' into feature/use-onyx-connection-manager
fabioh8010 Jul 1, 2024
15276d0
Return a object instead of tuple
fabioh8010 Jul 1, 2024
27c779b
Integrate the connection manager into withOnyx
fabioh8010 Jul 2, 2024
94e6bdc
Refactor Onyx.connect to use the connection manager
fabioh8010 Jul 2, 2024
4fa813d
Improve connection manager
fabioh8010 Jul 3, 2024
86a5347
Add fail safe logic to disconnect
fabioh8010 Jul 3, 2024
a45fa57
Unify reuseConnection and withOnyxInstance conditions
fabioh8010 Jul 3, 2024
d0753f6
Keep connect and disconnect functions to avoid TS error
fabioh8010 Jul 3, 2024
5819394
Add tests for useOnyx multiple usage
fabioh8010 Jul 5, 2024
d9ac00b
Fix evictable keys implementation
fabioh8010 Jul 7, 2024
3ca3b03
Merge remote-tracking branch 'origin/main' into feature/use-onyx-conn…
fabioh8010 Jul 8, 2024
213e8f5
Implement test for reuseConnection use case
fabioh8010 Jul 15, 2024
0b1ec56
Remove disconnectKey() and implement test for disconnectAll()
fabioh8010 Jul 15, 2024
1ff1db1
Improve disconnectAll() implementation
fabioh8010 Jul 15, 2024
3ed9856
Make initWithStoredValues option create unique connections
fabioh8010 Jul 15, 2024
0b9614e
Remove subscriptionID property from connection metadata
fabioh8010 Jul 15, 2024
8bca475
Merge tag 'v2.0.57' into feature/use-onyx-connection-manager
fabioh8010 Jul 30, 2024
365953d
Rename ConnectionMetadata to Connection
fabioh8010 Aug 2, 2024
0a62917
Add comments and refactor some variables
fabioh8010 Aug 5, 2024
80e56a5
Add tests for generateConnectionID
fabioh8010 Aug 5, 2024
717f025
Update descriptions
fabioh8010 Aug 5, 2024
62c4075
Remove self access to OnyxUtils
fabioh8010 Aug 5, 2024
3f1bf41
Merge branch 'main' into feature/use-onyx-connection-manager
fabioh8010 Aug 6, 2024
82b3899
Merge branch 'main' into feature/use-onyx-connection-manager
fabioh8010 Aug 7, 2024
c3b7c08
Fix tests
fabioh8010 Aug 7, 2024
c11c987
Change logs level
fabioh8010 Aug 7, 2024
da88b9b
Minor fixes
fabioh8010 Aug 7, 2024
cc7403e
Update docs
fabioh8010 Aug 14, 2024
52bbf42
Remove param from guid() function
fabioh8010 Aug 14, 2024
8fef114
Implement hasWithOnyxInstance() method
fabioh8010 Aug 20, 2024
5ac0fd1
Address review comments
fabioh8010 Aug 20, 2024
9b4759f
Send collection key on connect callback
fabioh8010 Aug 20, 2024
971819c
Update docs
fabioh8010 Aug 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 131 additions & 31 deletions API-INTERNAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
<dt><a href="#getMergeQueuePromise">getMergeQueuePromise()</a></dt>
<dd><p>Getter - returns the merge queue promise.</p>
</dd>
<dt><a href="#getCallbackToStateMapping">getCallbackToStateMapping()</a></dt>
<dd><p>Getter - returns the callback to state mapping.</p>
</dd>
<dt><a href="#getDefaultKeyStates">getDefaultKeyStates()</a></dt>
<dd><p>Getter - returns the default key states.</p>
</dd>
<dt><a href="#getDeferredInitTask">getDeferredInitTask()</a></dt>
<dd><p>Getter - returns the deffered init task.</p>
</dd>
<dt><a href="#getEvictionBlocklist">getEvictionBlocklist()</a></dt>
<dd><p>Getter - returns the eviction block list.</p>
</dd>
<dt><a href="#initStoreValues">initStoreValues(keys, initialKeyStates, safeEvictionKeys)</a></dt>
<dd><p>Sets the initial values for the Onyx store</p>
</dd>
Expand All @@ -34,11 +37,20 @@ The resulting collection will only contain items that are returned by the select
<dt><a href="#get">get()</a></dt>
<dd><p>Get some data from the store</p>
</dd>
<dt><a href="#storeKeyBySubscriptions">storeKeyBySubscriptions(subscriptionID, key)</a></dt>
<dd><p>Stores a subscription ID associated with a given key.</p>
</dd>
<dt><a href="#deleteKeyBySubscriptions">deleteKeyBySubscriptions(subscriptionID)</a></dt>
<dd><p>Deletes a subscription ID associated with its corresponding key.</p>
</dd>
<dt><a href="#getAllKeys">getAllKeys()</a></dt>
<dd><p>Returns current key names stored in persisted storage</p>
</dd>
<dt><a href="#getCollectionKeys">getCollectionKeys()</a></dt>
<dd><p>Returns set of all registered collection keys</p>
</dd>
<dt><a href="#isCollectionKey">isCollectionKey()</a></dt>
<dd><p>Checks to see if the a subscriber&#39;s supplied key
<dd><p>Checks to see if the subscriber&#39;s supplied key
is associated with a collection of keys.</p>
</dd>
<dt><a href="#splitCollectionMemberKey">splitCollectionMemberKey(key)</a> ⇒</dt>
Expand All @@ -51,6 +63,15 @@ or if the provided key is a collection member key (in case our configured key is
<dt><a href="#isSafeEvictionKey">isSafeEvictionKey()</a></dt>
<dd><p>Checks to see if this key has been flagged as safe for removal.</p>
</dd>
<dt><a href="#getCollectionKey">getCollectionKey(key)</a> ⇒ <code>string</code></dt>
<dd><p>It extracts the non-numeric collection identifier of a given key.</p>
<p>For example:</p>
<ul>
<li><code>getCollectionKey(&quot;report_123&quot;)</code> would return &quot;report_&quot;</li>
<li><code>getCollectionKey(&quot;report&quot;)</code> would return &quot;report&quot;</li>
<li><code>getCollectionKey(&quot;report_&quot;)</code> would return &quot;report_&quot;</li>
</ul>
</dd>
<dt><a href="#tryGetCachedValue">tryGetCachedValue()</a></dt>
<dd><p>Tries to get a value from the cache. If the value is not present in cache it will return the default value or undefined.
If the requested key is a collection, it will return an object with all the collection members.</p>
Expand All @@ -63,13 +84,6 @@ If the requested key is a collection, it will return an object with all the coll
recently accessed key should be at the head and the most
recently accessed key at the tail.</p>
</dd>
<dt><a href="#removeFromEvictionBlockList">removeFromEvictionBlockList()</a></dt>
<dd><p>Removes a key previously added to this list
which will enable it to be deleted again.</p>
</dd>
<dt><a href="#addToEvictionBlockList">addToEvictionBlockList()</a></dt>
<dd><p>Keys added to this list can never be deleted.</p>
</dd>
<dt><a href="#addAllSafeEvictionKeysToRecentlyAccessedList">addAllSafeEvictionKeysToRecentlyAccessedList()</a></dt>
<dd><p>Take all the keys that are safe to evict and add them to
the recently accessed list when initializing the app. This
Expand Down Expand Up @@ -129,6 +143,18 @@ to an array of key-value pairs in the above format and removes key-value pairs t
<dt><a href="#initializeWithDefaultKeyStates">initializeWithDefaultKeyStates()</a></dt>
<dd><p>Merge user provided default key value pairs.</p>
</dd>
<dt><a href="#isValidNonEmptyCollectionForMerge">isValidNonEmptyCollectionForMerge()</a></dt>
<dd><p>Validate the collection is not empty and has a correct type before applying mergeCollection()</p>
</dd>
<dt><a href="#doAllCollectionItemsBelongToSameParent">doAllCollectionItemsBelongToSameParent()</a></dt>
<dd><p>Verify if all the collection keys belong to the same parent</p>
</dd>
<dt><a href="#subscribeToKey">subscribeToKey(connectOptions)</a> ⇒</dt>
<dd><p>Subscribes to an Onyx key and listens to its changes.</p>
</dd>
<dt><a href="#unsubscribeFromKey">unsubscribeFromKey(subscriptionID)</a></dt>
<dd><p>Disconnects and removes the listener from the Onyx key.</p>
</dd>
</dl>

<a name="getMergeQueue"></a>
Expand All @@ -142,18 +168,24 @@ Getter - returns the merge queue.
## getMergeQueuePromise()
Getter - returns the merge queue promise.

**Kind**: global function
<a name="getCallbackToStateMapping"></a>

## getCallbackToStateMapping()
Getter - returns the callback to state mapping.

**Kind**: global function
<a name="getDefaultKeyStates"></a>

## getDefaultKeyStates()
Getter - returns the default key states.

**Kind**: global function
<a name="getDeferredInitTask"></a>

## getDeferredInitTask()
Getter - returns the deffered init task.

**Kind**: global function
<a name="getEvictionBlocklist"></a>

## getEvictionBlocklist()
Getter - returns the eviction block list.

**Kind**: global function
<a name="initStoreValues"></a>

Expand Down Expand Up @@ -191,16 +223,45 @@ The resulting collection will only contain items that are returned by the select
Get some data from the store

**Kind**: global function
<a name="storeKeyBySubscriptions"></a>

## storeKeyBySubscriptions(subscriptionID, key)
Stores a subscription ID associated with a given key.

**Kind**: global function

| Param | Description |
| --- | --- |
| subscriptionID | A subscription ID of the subscriber. |
| key | A key that the subscriber is subscribed to. |

<a name="deleteKeyBySubscriptions"></a>

## deleteKeyBySubscriptions(subscriptionID)
Deletes a subscription ID associated with its corresponding key.

**Kind**: global function

| Param | Description |
| --- | --- |
| subscriptionID | The subscription ID to be deleted. |

<a name="getAllKeys"></a>

## getAllKeys()
Returns current key names stored in persisted storage

**Kind**: global function
<a name="getCollectionKeys"></a>

## getCollectionKeys()
Returns set of all registered collection keys

**Kind**: global function
<a name="isCollectionKey"></a>

## isCollectionKey()
Checks to see if the a subscriber's supplied key
Checks to see if the subscriber's supplied key
is associated with a collection of keys.

**Kind**: global function
Expand Down Expand Up @@ -229,6 +290,23 @@ or if the provided key is a collection member key (in case our configured key is
Checks to see if this key has been flagged as safe for removal.

**Kind**: global function
<a name="getCollectionKey"></a>

## getCollectionKey(key) ⇒ <code>string</code>
It extracts the non-numeric collection identifier of a given key.

For example:
- `getCollectionKey("report_123")` would return "report_"
- `getCollectionKey("report")` would return "report"
- `getCollectionKey("report_")` would return "report_"

**Kind**: global function
**Returns**: <code>string</code> - The pure key without any numeric

| Param | Type | Description |
| --- | --- | --- |
| key | <code>OnyxKey</code> | The key to process. |

<a name="tryGetCachedValue"></a>

## tryGetCachedValue()
Expand All @@ -249,19 +327,6 @@ Add a key to the list of recently accessed keys. The least
recently accessed key should be at the head and the most
recently accessed key at the tail.

**Kind**: global function
<a name="removeFromEvictionBlockList"></a>

## removeFromEvictionBlockList()
Removes a key previously added to this list
which will enable it to be deleted again.

**Kind**: global function
<a name="addToEvictionBlockList"></a>

## addToEvictionBlockList()
Keys added to this list can never be deleted.

**Kind**: global function
<a name="addAllSafeEvictionKeysToRecentlyAccessedList"></a>

Expand Down Expand Up @@ -399,3 +464,38 @@ Merges an array of changes with an existing value
Merge user provided default key value pairs.

**Kind**: global function
<a name="isValidNonEmptyCollectionForMerge"></a>

## isValidNonEmptyCollectionForMerge()
Validate the collection is not empty and has a correct type before applying mergeCollection()

**Kind**: global function
<a name="doAllCollectionItemsBelongToSameParent"></a>

## doAllCollectionItemsBelongToSameParent()
Verify if all the collection keys belong to the same parent

**Kind**: global function
<a name="subscribeToKey"></a>

## subscribeToKey(connectOptions) ⇒
Subscribes to an Onyx key and listens to its changes.

**Kind**: global function
**Returns**: The subscription ID to use when calling `OnyxUtils.unsubscribeFromKey()`.

| Param | Description |
| --- | --- |
| connectOptions | The options object that will define the behavior of the connection. |

<a name="unsubscribeFromKey"></a>

## unsubscribeFromKey(subscriptionID)
Disconnects and removes the listener from the Onyx key.

**Kind**: global function

| Param | Description |
| --- | --- |
| subscriptionID | Subscription ID returned by calling `OnyxUtils.subscribeToKey()`. |

50 changes: 27 additions & 23 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
<dt><a href="#init">init()</a></dt>
<dd><p>Initialize the store with actions and listening for storage events</p>
</dd>
<dt><a href="#connect">connect(mapping)</a> ⇒</dt>
<dd><p>Subscribes a react component&#39;s state directly to a store key</p>
<dt><a href="#connect">connect(connectOptions)</a> ⇒</dt>
<dd><p>Connects to an Onyx key given the options passed and listens to its changes.</p>
</dd>
<dt><a href="#disconnect">disconnect(connectionID)</a></dt>
<dd><p>Remove the listener for a react component</p>
<dt><a href="#disconnect">disconnect(connection)</a></dt>
<dd><p>Disconnects and removes the listener from the Onyx key.</p>
</dd>
<dt><a href="#set">set(key, value)</a></dt>
<dd><p>Write a value to our store with the given key</p>
Expand Down Expand Up @@ -60,45 +60,49 @@ Initialize the store with actions and listening for storage events
**Kind**: global function
<a name="connect"></a>

## connect(mapping) ⇒
Subscribes a react component's state directly to a store key
## connect(connectOptions) ⇒
Connects to an Onyx key given the options passed and listens to its changes.

**Kind**: global function
**Returns**: an ID to use when calling disconnect
**Returns**: The connection object to use when calling `Onyx.disconnect()`.

| Param | Description |
| --- | --- |
| mapping | the mapping information to connect Onyx to the components state |
| mapping.key | ONYXKEY to subscribe to |
| [mapping.statePropertyName] | the name of the property in the state to connect the data to |
| [mapping.withOnyxInstance] | whose setState() method will be called with any changed data This is used by React components to connect to Onyx |
| [mapping.callback] | a method that will be called with changed data This is used by any non-React code to connect to Onyx |
| [mapping.initWithStoredValues] | If set to false, then no data will be prefilled into the component |
| [mapping.waitForCollectionCallback] | If set to true, it will return the entire collection to the callback as a single object |
| [mapping.selector] | THIS PARAM IS ONLY USED WITH withOnyx(). If included, this will be used to subscribe to a subset of an Onyx key's data. The sourceData and withOnyx state are passed to the selector and should return the simplified data. Using this setting on `withOnyx` can have very positive performance benefits because the component will only re-render when the subset of data changes. Otherwise, any change of data on any property would normally cause the component to re-render (and that can be expensive from a performance standpoint). |
| [mapping.initialValue] | THIS PARAM IS ONLY USED WITH withOnyx(). If included, this will be passed to the component so that something can be rendered while data is being fetched from the DB. Note that it will not cause the component to have the loading prop set to true. |
fabioh8010 marked this conversation as resolved.
Show resolved Hide resolved
| connectOptions | The options object that will define the behavior of the connection. |
| connectOptions.key | The Onyx key to subscribe to. |
| connectOptions.callback | A function that will be called when the Onyx data we are subscribed changes. |
| connectOptions.waitForCollectionCallback | If set to `true`, it will return the entire collection to the callback as a single object. |
| connectOptions.withOnyxInstance | The `withOnyx` class instance to be internally passed. **Only used inside `withOnyx()` HOC.** |
| connectOptions.statePropertyName | The name of the component's prop that is connected to the Onyx key. **Only used inside `withOnyx()` HOC.** |
| connectOptions.displayName | The component's display name. **Only used inside `withOnyx()` HOC.** |
| connectOptions.selector | This will be used to subscribe to a subset of an Onyx key's data. **Only used inside `useOnyx()` hook or `withOnyx()` HOC.** Using this setting on `useOnyx()` or `withOnyx()` can have very positive performance benefits because the component will only re-render when the subset of data changes. Otherwise, any change of data on any property would normally cause the component to re-render (and that can be expensive from a performance standpoint). |

**Example**
```js
const connectionID = Onyx.connect({
```ts
const connection = Onyx.connect({
key: ONYXKEYS.SESSION,
callback: onSessionChange,
});
```
<a name="disconnect"></a>

## disconnect(connectionID)
Remove the listener for a react component
## disconnect(connection)
Disconnects and removes the listener from the Onyx key.

**Kind**: global function

| Param | Description |
| --- | --- |
| connectionID | unique id returned by call to Onyx.connect() |
| connection | Connection object returned by calling `Onyx.connect()`. |

**Example**
```js
Onyx.disconnect(connectionID);
```ts
const connection = Onyx.connect({
key: ONYXKEYS.SESSION,
callback: onSessionChange,
});

Onyx.disconnect(connection);
```
<a name="set"></a>

Expand Down
Loading
Loading