diff --git a/API.md b/API.md index 9f2055ba1..82183ea0c 100644 --- a/API.md +++ b/API.md @@ -15,9 +15,6 @@ This method will be deprecated soon. Please use Onyx.connectWithoutView()<
connectWithoutView(connectOptions) ⇒

Connects to an Onyx key given the options passed and listens to its changes.

-
disconnect(connection)
-

Disconnects and removes the listener from the Onyx key.

-
set(key, value, options)

Write a value to our store with the given key

@@ -91,7 +88,7 @@ Connects to an Onyx key given the options passed and listens to its changes. This method will be deprecated soon. Please use `Onyx.connectWithoutView()` instead. **Kind**: global function -**Returns**: The `Connection` handle to use when calling `Onyx.disconnect()`. +**Returns**: The `Connection` handle whose `unsubscribe()` stops this subscription. | Param | Description | | --- | --- | @@ -118,7 +115,7 @@ cache after any same-tick writes have applied. Connects to an Onyx key given the options passed and listens to its changes. **Kind**: global function -**Returns**: The `Connection` handle to use when calling `Onyx.disconnect()`. +**Returns**: The `Connection` handle whose `unsubscribe()` stops this subscription. | Param | Description | | --- | --- | @@ -139,26 +136,6 @@ object whenever any member changes; signature `(collection, collectionKey)`. For any other key, the callback fires with the value at that key; signature `(value, key)`. Initial fire is deferred via `scheduleInitialSubscriberNotification` so it reads cache after any same-tick writes have applied. - - -## disconnect(connection) -Disconnects and removes the listener from the Onyx key. - -**Kind**: global function - -| Param | Description | -| --- | --- | -| connection | Connection object returned by calling `Onyx.connect()` or `Onyx.connectWithoutView()`. | - -**Example** -```ts -const connection = Onyx.connectWithoutView({ - key: ONYXKEYS.SESSION, - callback: onSessionChange, -}); - -Onyx.disconnect(connection); -``` ## set(key, value, options) diff --git a/README.md b/README.md index 5b068db1a..2d6d4e071 100644 --- a/README.md +++ b/README.md @@ -130,10 +130,10 @@ const connection = Onyx.connectWithoutView({ }); ``` -To teardown the subscription call `Onyx.disconnect()` with the connection returned from `Onyx.connectWithoutView()`. It's recommended to clean up subscriptions anytime you are connecting from within a function to prevent memory leaks. +To teardown the subscription call `unsubscribe()` on the connection returned from `Onyx.connectWithoutView()`. It's recommended to clean up subscriptions anytime you are connecting from within a function to prevent memory leaks. ```javascript -Onyx.disconnect(connection); +connection.unsubscribe(); ``` We can also access values inside React function components via the `useOnyx()` [hook](https://react.dev/reference/react/hooks). When the data changes the component will re-render. diff --git a/lib/Onyx.ts b/lib/Onyx.ts index 72c76c608..e5df45366 100644 --- a/lib/Onyx.ts +++ b/lib/Onyx.ts @@ -140,7 +140,7 @@ function init({ * @param connectOptions The options object that will define the behavior of the connection. * @param connectOptions.key The Onyx key to subscribe to. * @param connectOptions.callback A function that will be called when the Onyx data we are subscribed changes. - * @returns The `Connection` handle to use when calling `Onyx.disconnect()`. + * @returns The `Connection` handle whose `unsubscribe()` stops this subscription. */ function connect(connectOptions: ConnectOptions): Connection { const {key, callback} = connectOptions; @@ -236,34 +236,12 @@ function connect(connectOptions: ConnectOptions): Co * @param connectOptions The options object that will define the behavior of the connection. * @param connectOptions.key The Onyx key to subscribe to. * @param connectOptions.callback A function that will be called when the Onyx data we are subscribed changes. - * @returns The `Connection` handle to use when calling `Onyx.disconnect()`. + * @returns The `Connection` handle whose `unsubscribe()` stops this subscription. */ function connectWithoutView(connectOptions: ConnectOptions): Connection { return connect(connectOptions); } -/** - * Disconnects and removes the listener from the Onyx key. - * - * @example - * ```ts - * const connection = Onyx.connectWithoutView({ - * key: ONYXKEYS.SESSION, - * callback: onSessionChange, - * }); - * - * Onyx.disconnect(connection); - * ``` - * - * @param connection Connection object returned by calling `Onyx.connect()` or `Onyx.connectWithoutView()`. - */ -function disconnect(connection: Connection): void { - if (!connection) { - return; - } - connection.unsubscribe(); -} - /** * Write a value to our store with the given key * @@ -801,7 +779,6 @@ const Onyx = { METHOD: OnyxUtils.METHOD, connect, connectWithoutView, - disconnect, set, multiSet, merge, diff --git a/lib/types.ts b/lib/types.ts index 165033e0d..cbf4d861b 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -407,7 +407,7 @@ type MixedOperationsQueue = { /** * Represents a connection to an Onyx key, returned by `Onyx.connect()`/`Onyx.connectWithoutView()`. - * Pass it to `Onyx.disconnect()` to stop receiving callbacks for this subscription. + * Call its `unsubscribe()` to stop receiving callbacks for this subscription. */ type Connection = { /** Unsubscribe this connection. Idempotent. */ diff --git a/tests/unit/onyxClearNativeStorageTest.ts b/tests/unit/onyxClearNativeStorageTest.ts index a069d406d..3f8fdec69 100644 --- a/tests/unit/onyxClearNativeStorageTest.ts +++ b/tests/unit/onyxClearNativeStorageTest.ts @@ -41,7 +41,7 @@ describe('Set data while storage is clearing', () => { afterEach(() => { if (connection) { - Onyx.disconnect(connection); + connection.unsubscribe(); } return Onyx.clear(); }); diff --git a/tests/unit/onyxClearWebStorageTest.ts b/tests/unit/onyxClearWebStorageTest.ts index b9ed84dcf..b0bc31398 100644 --- a/tests/unit/onyxClearWebStorageTest.ts +++ b/tests/unit/onyxClearWebStorageTest.ts @@ -43,7 +43,7 @@ describe('Set data while storage is clearing', () => { afterEach(() => { if (connection) { - Onyx.disconnect(connection); + connection.unsubscribe(); } return Onyx.clear(); }); @@ -229,7 +229,7 @@ describe('Set data while storage is clearing', () => { // When onyx is cleared .then(() => Onyx.clear()) .then(() => { - Onyx.disconnect(testConnection); + testConnection.unsubscribe(); }) .then(() => { // Then the collection callback should only have been called three times: diff --git a/tests/unit/onyxTest.ts b/tests/unit/onyxTest.ts index 954443a18..9d7ed3567 100644 --- a/tests/unit/onyxTest.ts +++ b/tests/unit/onyxTest.ts @@ -61,7 +61,7 @@ describe('Onyx', () => { afterEach(() => { if (connection) { - Onyx.disconnect(connection); + connection.unsubscribe(); } return Onyx.clear(); }); @@ -354,7 +354,7 @@ describe('Onyx', () => { // Expect that the connection to a key with a default value that wasn't changed is not called on clear expect(mockCallback).toHaveBeenCalledTimes(0); - return Onyx.disconnect(otherTestConnection); + return otherTestConnection.unsubscribe(); }); }); @@ -400,7 +400,7 @@ describe('Onyx', () => { .then(() => { expect(testKeyValue).toBe('test'); if (connection) { - Onyx.disconnect(connection); + connection.unsubscribe(); } return Onyx.set(ONYX_KEYS.TEST_KEY, 'test updated'); }) @@ -1279,7 +1279,7 @@ describe('Onyx', () => { // We set an initial value of 42 for ONYX_KEYS.OTHER_TEST in Onyx.init() expect(otherTestCallback).toHaveBeenNthCalledWith(1, 42, ONYX_KEYS.OTHER_TEST); expect(otherTestCallback).toHaveBeenNthCalledWith(2, 'pizza', ONYX_KEYS.OTHER_TEST); - for (const id of connections) Onyx.disconnect(id); + for (const id of connections) id.unsubscribe(); }), ); }); @@ -1538,7 +1538,7 @@ describe('Onyx', () => { expect(dogCallback).toHaveBeenNthCalledWith(1, undefined, dog); expect(dogCallback).toHaveBeenLastCalledWith({name: 'Rex'}, dog); - connections.map((id) => Onyx.disconnect(id)); + connections.map((id) => id.unsubscribe()); }); }); @@ -1769,7 +1769,7 @@ describe('Onyx', () => { ONYX_KEYS.COLLECTION.ROUTES, ); - connections.map((id) => Onyx.disconnect(id)); + connections.map((id) => id.unsubscribe()); }); }); @@ -1856,7 +1856,7 @@ describe('Onyx', () => { ONYX_KEYS.COLLECTION.PEOPLE, ); - connections.map((id) => Onyx.disconnect(id)); + connections.map((id) => id.unsubscribe()); }); }); @@ -2427,8 +2427,8 @@ describe('Onyx', () => { expect(individualCallback1).toHaveBeenCalledWith({id: '1', name: 'Updated Item 1'}, key1); expect(individualCallback2).toHaveBeenCalledWith({id: '2', name: 'Updated Item 2'}, key2); - Onyx.disconnect(connection1); - Onyx.disconnect(connection2); + connection1.unsubscribe(); + connection2.unsubscribe(); }); it('should not save a RAM-only collection to storage', async () => { @@ -4048,7 +4048,7 @@ describe('RAM-only keys should not read from storage', () => { expect(receivedValue).toBeUndefined(); expect(cache.get(ONYX_KEYS.RAM_ONLY_TEST_KEY)).toBeUndefined(); - Onyx.disconnect(connection); + connection.unsubscribe(); }); it('should not return stale storage data for RAM-only collection members via multiGet', async () => { @@ -4078,7 +4078,7 @@ describe('RAM-only keys should not read from storage', () => { expect(cache.get(collectionMember1)).toBeUndefined(); expect(cache.get(collectionMember2)).toBeUndefined(); - Onyx.disconnect(connection); + connection.unsubscribe(); }); it('should not include stale RAM-only keys in getAllKeys results', async () => { @@ -4159,7 +4159,7 @@ describe('RAM-only keys should not read from storage', () => { // Should never receive the stale value expect(receivedValues.every((v) => v === undefined || v === null)).toBe(true); - Onyx.disconnect(connection); + connection.unsubscribe(); }); it('should still work correctly for normal keys when RAM-only keys have stale storage data', async () => { @@ -4195,8 +4195,8 @@ describe('RAM-only keys should not read from storage', () => { // RAM-only key should NOT read stale value from storage expect(ramOnlyValue).toBeUndefined(); - Onyx.disconnect(connection1); - Onyx.disconnect(connection2); + connection1.unsubscribe(); + connection2.unsubscribe(); }); it('should not sync RAM-only keys from other instances via keepInstancesSync', async () => { @@ -4243,8 +4243,8 @@ describe('RAM-only keys should not read from storage', () => { expect(normalValue).toEqual('synced_normal_value'); - Onyx.disconnect(connection); - Onyx.disconnect(connection2); + connection.unsubscribe(); + connection2.unsubscribe(); }); it('should notify collection-root and collection member subscribers when a collection member syncs from another instance', async () => { @@ -4291,8 +4291,8 @@ describe('RAM-only keys should not read from storage', () => { // The collection member subscriber must receive the synced data. expect(collectionMember2).toEqual({name: 'entry 2 changed'}); - Onyx.disconnect(collectionConn); - Onyx.disconnect(collectionMember2Conn); + collectionConn.unsubscribe(); + collectionMember2Conn.unsubscribe(); }); it('should notify a collection-root subscriber once when multiple members sync from another instance', async () => { @@ -4333,7 +4333,7 @@ describe('RAM-only keys should not read from storage', () => { expect(collection[`${ONYX_KEYS.COLLECTION.TEST_KEY}2`]).toEqual({name: 'entry 2'}); expect(collection[`${ONYX_KEYS.COLLECTION.TEST_KEY}3`]).toEqual({name: 'entry 3 changed'}); - Onyx.disconnect(connection); + connection.unsubscribe(); }); it('should notify subscribers with undefined when a collection member is removed in another instance', async () => { @@ -4378,8 +4378,8 @@ describe('RAM-only keys should not read from storage', () => { // The collection-root subscriber must receive the collection without the removed member. expect(collection).toEqual({[`${ONYX_KEYS.COLLECTION.TEST_KEY}1`]: {name: 'entry 1'}}); - Onyx.disconnect(collectionConn); - Onyx.disconnect(collectionMember2Conn); + collectionConn.unsubscribe(); + collectionMember2Conn.unsubscribe(); }); it('should serve RAM-only keys from cache and normal keys from storage in multiGet', async () => { @@ -4437,7 +4437,7 @@ describe('RAM-only keys should not read from storage', () => { const storageValue = await StorageMock.getItem(ONYX_KEYS.RAM_ONLY_TEST_KEY); expect(storageValue).toEqual('stale_value'); - Onyx.disconnect(connection); + connection.unsubscribe(); }); }); diff --git a/tests/unit/onyxUtilsTest.ts b/tests/unit/onyxUtilsTest.ts index 779786958..f9a0c7189 100644 --- a/tests/unit/onyxUtilsTest.ts +++ b/tests/unit/onyxUtilsTest.ts @@ -141,7 +141,7 @@ describe('OnyxUtils', () => { [routeB1]: {name: 'Route B1'}, [routeC]: {name: 'New Route C'}, }); - await Onyx.disconnect(connection); + connection.unsubscribe(); }); it('should not replace anything in the collection with empty values', async () => { @@ -165,7 +165,7 @@ describe('OnyxUtils', () => { expect(result).toEqual({ [routeA]: {name: 'Route A'}, }); - await Onyx.disconnect(connection); + connection.unsubscribe(); }); it('should reject collection items with invalid keys', async () => { @@ -193,7 +193,7 @@ describe('OnyxUtils', () => { [routeA]: {name: 'Route A'}, }); - await Onyx.disconnect(connection); + connection.unsubscribe(); }); }); @@ -222,7 +222,7 @@ describe('OnyxUtils', () => { expect(collection[`${ONYXKEYS.COLLECTION.TEST_KEY}2`]).toEqual({id: 2}); expect(collection[`${ONYXKEYS.COLLECTION.TEST_KEY}3`]).toEqual({id: 3}); - Onyx.disconnect(connection); + connection.unsubscribe(); }); it('should fire individual member-key subscribers once per key', async () => { @@ -260,9 +260,9 @@ describe('OnyxUtils', () => { expect(spy3).toHaveBeenCalledTimes(1); expect(spy3).toHaveBeenCalledWith({id: 3}, `${ONYXKEYS.COLLECTION.TEST_KEY}3`); - Onyx.disconnect(conn1); - Onyx.disconnect(conn2); - Onyx.disconnect(conn3); + conn1.unsubscribe(); + conn2.unsubscribe(); + conn3.unsubscribe(); }); it('should notify non-collection keys individually alongside batched collection updates', async () => { @@ -294,8 +294,8 @@ describe('OnyxUtils', () => { expect(singleKeyCallback).toHaveBeenCalledTimes(1); expect(singleKeyCallback).toHaveBeenCalledWith('standalone', ONYXKEYS.TEST_KEY); - Onyx.disconnect(connCollection); - Onyx.disconnect(connSingle); + connCollection.unsubscribe(); + connSingle.unsubscribe(); }); it('should batch notifications per-collection when members span multiple collections', async () => { @@ -326,8 +326,8 @@ describe('OnyxUtils', () => { expect(testCallback).toHaveBeenCalledTimes(1); expect(routesCallback).toHaveBeenCalledTimes(1); - Onyx.disconnect(connTest); - Onyx.disconnect(connRoutes); + connTest.unsubscribe(); + connRoutes.unsubscribe(); }); it('should pass previous values to keysChanged so unchanged members skip notification', async () => { @@ -367,8 +367,8 @@ describe('OnyxUtils', () => { // because keysChanged sees the same reference as previousCollection[key] expect(spy2).not.toHaveBeenCalled(); - Onyx.disconnect(conn1); - Onyx.disconnect(conn2); + conn1.unsubscribe(); + conn2.unsubscribe(); }); it('should not fire again for a collection subscriber that disconnects itself in its callback', async () => { @@ -382,7 +382,7 @@ describe('OnyxUtils', () => { await waitForPromisesToResolve(); callback.mockReset(); callback.mockImplementation(() => { - Onyx.disconnect(connection); + connection.unsubscribe(); }); // First batch fires the collection callback once, which disconnects the subscriber. @@ -445,8 +445,8 @@ describe('OnyxUtils', () => { // keyB subscriber's last received value matches the cache (no stale callback) expect(callbackB.mock.calls.at(1)?.[0]).toBe('multiSetB'); - Onyx.disconnect(connA); - Onyx.disconnect(connB); + connA.unsubscribe(); + connB.unsubscribe(); }); });