diff --git a/src/store/RelayContext.js b/src/store/RelayContext.js new file mode 100644 index 0000000000000..e8a2f41dcfb69 --- /dev/null +++ b/src/store/RelayContext.js @@ -0,0 +1,247 @@ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule RelayContext + * @typechecks + * @flow + */ + +'use strict'; + +const GraphQLFragmentPointer = require('GraphQLFragmentPointer'); +import type {GarbageCollectionScheduler} from 'RelayGarbageCollector'; +import type RelayMutation from 'RelayMutation'; +import type RelayMutationTransaction from 'RelayMutationTransaction'; +import type RelayQuery from 'RelayQuery'; +const RelayQueryResultObservable = require('RelayQueryResultObservable'); +const RelayStoreData = require('RelayStoreData'); + +const forEachRootCallArg = require('forEachRootCallArg'); +const readRelayQueryData = require('readRelayQueryData'); +const warning = require('warning'); + +import type { + Abortable, + Observable, + RelayMutationTransactionCommitCallbacks, + ReadyStateChangeCallback, + StoreReaderData, + StoreReaderOptions, +} from 'RelayTypes'; + +import type { + DataID, + RelayQuerySet, +} from 'RelayInternalTypes'; + +/** + * @public + * + * RelayContext is a caching layer that records GraphQL response data and enables + * resolving and subscribing to queries. + * + * === onReadyStateChange === + * + * Whenever Relay sends a request for data via GraphQL, an "onReadyStateChange" + * callback can be supplied. This callback is called one or more times with a + * `readyState` object with the following properties: + * + * aborted: Whether the request was aborted. + * done: Whether all response data has been fetched. + * error: An error in the event of a failure, or null if none. + * ready: Whether the queries are at least partially resolvable. + * stale: When resolvable during `forceFetch`, whether data is stale. + * + * If the callback is invoked with `aborted`, `done`, or a non-null `error`, the + * callback will never be called again. Example usage: + * + * function onReadyStateChange(readyState) { + * if (readyState.aborted) { + * // Request was aborted. + * } else if (readyState.error) { + * // Failure occurred. + * } else if (readyState.ready) { + * // Queries are at least partially resolvable. + * if (readyState.done) { + * // Queries are completely resolvable. + * } + * } + * } + * + */ +class RelayContext { + _storeData: RelayStoreData; + + constructor(storeData: RelayStoreData) { + this._storeData = storeData; + } + + /** + * Primes the store by sending requests for any missing data that would be + * required to satisfy the supplied set of queries. + */ + primeCache( + querySet: RelayQuerySet, + callback: ReadyStateChangeCallback + ): Abortable { + return this._storeData.getQueryRunner().run(querySet, callback); + } + + /** + * Forces the supplied set of queries to be fetched and written to the store. + * Any data that previously satisfied the queries will be overwritten. + */ + forceFetch( + querySet: RelayQuerySet, + callback: ReadyStateChangeCallback + ): Abortable { + return this._storeData.getQueryRunner().forceFetch(querySet, callback); + } + + /** + * Reads query data anchored at the supplied data ID. + */ + read( + node: RelayQuery.Node, + dataID: DataID, + options?: StoreReaderOptions + ): ?StoreReaderData { + return readRelayQueryData(this._storeData, node, dataID, options).data; + } + + /** + * Reads query data anchored at the supplied data IDs. + */ + readAll( + node: RelayQuery.Node, + dataIDs: Array, + options?: StoreReaderOptions + ): Array { + return dataIDs.map( + dataID => readRelayQueryData(this._storeData, node, dataID, options).data + ); + } + + /** + * Reads query data, where each element in the result array corresponds to a + * root call argument. If the root call has no arguments, the result array + * will contain exactly one element. + */ + readQuery( + root: RelayQuery.Root, + options?: StoreReaderOptions + ): Array { + const storageKey = root.getStorageKey(); + const results = []; + forEachRootCallArg(root, identifyingArgValue => { + let data; + const dataID = this._storeData.getQueuedStore() + .getDataID(storageKey, identifyingArgValue); + if (dataID != null) { + data = this.read(root, dataID, options); + } + results.push(data); + }); + return results; + } + + /** + * Reads and subscribes to query data anchored at the supplied data ID. The + * returned observable emits updates as the data changes over time. + */ + observe( + fragment: RelayQuery.Fragment, + dataID: DataID + ): Observable { + const fragmentPointer = new GraphQLFragmentPointer( + fragment.isPlural()? [dataID] : dataID, + fragment + ); + return new RelayQueryResultObservable(this._storeData, fragmentPointer); + } + + /** + * Adds an update to the store without committing it. The returned + * RelayMutationTransaction can be committed or rolled back at a later time. + */ + applyUpdate( + mutation: RelayMutation, + callbacks?: RelayMutationTransactionCommitCallbacks + ): RelayMutationTransaction { + return this._storeData.getMutationQueue().createTransaction( + mutation, + callbacks + ); + } + + /** + * Adds an update to the store and commits it immediately. Returns + * the RelayMutationTransaction. + */ + commitUpdate( + mutation: RelayMutation, + callbacks?: RelayMutationTransactionCommitCallbacks + ): RelayMutationTransaction { + const transaction = this.applyUpdate(mutation, callbacks); + transaction.commit(); + return transaction; + } + + /** + * @deprecated + * + * Method renamed to commitUpdate + */ + update( + mutation: RelayMutation, + callbacks?: RelayMutationTransactionCommitCallbacks + ): void { + warning( + false, + '`RelayContext.update` is deprecated. Please use' + + ' `RelayContext.commitUpdate` or `RelayContext.applyUpdate` instead.' + ); + this.commitUpdate(mutation, callbacks); + } + + /** + * Creates a garbage collector for this instance. After initialization all + * newly added DataIDs will be registered in the created garbage collector. + * This will show a warning if data has already been added to the instance. + */ + initializeGarbageCollection(scheduler: GarbageCollectionScheduler): void { + this._storeData.initializeGarbageCollector(scheduler); + } + + /** + * Collects any un-referenced records in the store. + */ + scheduleGarbageCollection(): void { + const garbageCollector = this._storeData.getGarbageCollector(); + + if (garbageCollector) { + garbageCollector.collect(); + } + } + + /** + * Collects any un-referenced records reachable from the given record via + * graph traversal of fields. + * + * NOTE: If the given record is still referenced, no records are collected. + */ + scheduleGarbageCollectionFromNode(dataID: DataID): void { + const garbageCollector = this._storeData.getGarbageCollector(); + + if (garbageCollector) { + garbageCollector.collectFromNode(dataID); + } + } +} + +module.exports = RelayContext; diff --git a/src/store/RelayGarbageCollection.js b/src/store/RelayGarbageCollection.js index 502577293b233..b04f3763b9377 100644 --- a/src/store/RelayGarbageCollection.js +++ b/src/store/RelayGarbageCollection.js @@ -14,6 +14,7 @@ 'use strict'; import type {DataID} from 'RelayInternalTypes'; +const RelayStore = require('RelayStore'); const RelayStoreData = require('RelayStoreData'); const RelayTaskScheduler = require('RelayTaskScheduler'); @@ -44,21 +45,14 @@ var RelayGarbageCollection = { stepLength ); _stepLength = stepLength; - RelayStoreData - .getDefaultInstance() - .initializeGarbageCollector(scheduler); + RelayStore.initializeGarbageCollection(scheduler); }, /** * Collects any un-referenced records in the store. */ scheduleCollection(): void { - var garbageCollector = - RelayStoreData.getDefaultInstance().getGarbageCollector(); - - if (garbageCollector) { - garbageCollector.collect(); - } + RelayStore.scheduleGarbageCollection(); }, /** @@ -68,12 +62,7 @@ var RelayGarbageCollection = { * NOTE: If the given record is still referenced, no records are collected. */ scheduleCollectionFromNode(dataID: DataID): void { - var garbageCollector = - RelayStoreData.getDefaultInstance().getGarbageCollector(); - - if (garbageCollector) { - garbageCollector.collectFromNode(dataID); - } + RelayStore.scheduleGarbageCollectionFromNode(dataID); }, }; diff --git a/src/store/RelayStore.js b/src/store/RelayStore.js index 5681f4376554d..76fd5139b33d9 100644 --- a/src/store/RelayStore.js +++ b/src/store/RelayStore.js @@ -13,198 +13,7 @@ 'use strict'; -const GraphQLFragmentPointer = require('GraphQLFragmentPointer'); -import type RelayMutation from 'RelayMutation'; -const RelayMutationTransaction = require('RelayMutationTransaction'); -const RelayQuery = require('RelayQuery'); -const RelayQueryResultObservable = require('RelayQueryResultObservable'); +const RelayContext = require('RelayContext'); const RelayStoreData = require('RelayStoreData'); -const forEachRootCallArg = require('forEachRootCallArg'); -const readRelayQueryData = require('readRelayQueryData'); -const warning = require('warning'); - -import type { - Abortable, - Observable, - RelayMutationTransactionCommitCallbacks, - ReadyStateChangeCallback, - StoreReaderData, - StoreReaderOptions, -} from 'RelayTypes'; - -import type { - DataID, - RelayQuerySet, -} from 'RelayInternalTypes'; - -var storeData = RelayStoreData.getDefaultInstance(); -var queryRunner = storeData.getQueryRunner(); -var queuedStore = storeData.getQueuedStore(); - -/** - * @public - * - * RelayStore is a caching layer that records GraphQL response data and enables - * resolving and subscribing to queries. - * - * === onReadyStateChange === - * - * Whenever Relay sends a request for data via GraphQL, an "onReadyStateChange" - * callback can be supplied. This callback is called one or more times with a - * `readyState` object with the following properties: - * - * aborted: Whether the request was aborted. - * done: Whether all response data has been fetched. - * error: An error in the event of a failure, or null if none. - * ready: Whether the queries are at least partially resolvable. - * stale: When resolvable during `forceFetch`, whether data is stale. - * - * If the callback is invoked with `aborted`, `done`, or a non-null `error`, the - * callback will never be called again. Example usage: - * - * function onReadyStateChange(readyState) { - * if (readyState.aborted) { - * // Request was aborted. - * } else if (readyState.error) { - * // Failure occurred. - * } else if (readyState.ready) { - * // Queries are at least partially resolvable. - * if (readyState.done) { - * // Queries are completely resolvable. - * } - * } - * } - * - */ -var RelayStore = { - - /** - * Primes the store by sending requests for any missing data that would be - * required to satisfy the supplied set of queries. - */ - primeCache( - querySet: RelayQuerySet, - callback: ReadyStateChangeCallback - ): Abortable { - return queryRunner.run(querySet, callback); - }, - - /** - * Forces the supplied set of queries to be fetched and written to the store. - * Any data that previously satisfied the queries will be overwritten. - */ - forceFetch( - querySet: RelayQuerySet, - callback: ReadyStateChangeCallback - ): Abortable { - return queryRunner.forceFetch(querySet, callback); - }, - - /** - * Reads query data anchored at the supplied data ID. - */ - read( - node: RelayQuery.Node, - dataID: DataID, - options?: StoreReaderOptions - ): ?StoreReaderData { - return readRelayQueryData(storeData, node, dataID, options).data; - }, - - /** - * Reads query data anchored at the supplied data IDs. - */ - readAll( - node: RelayQuery.Node, - dataIDs: Array, - options?: StoreReaderOptions - ): Array { - return dataIDs.map( - dataID => readRelayQueryData(storeData, node, dataID, options).data - ); - }, - - /** - * Reads query data, where each element in the result array corresponds to a - * root call argument. If the root call has no arguments, the result array - * will contain exactly one element. - */ - readQuery( - root: RelayQuery.Root, - options?: StoreReaderOptions - ): Array { - const storageKey = root.getStorageKey(); - var results = []; - forEachRootCallArg(root, identifyingArgValue => { - var data; - var dataID = queuedStore.getDataID(storageKey, identifyingArgValue); - if (dataID != null) { - data = RelayStore.read(root, dataID, options); - } - results.push(data); - }); - return results; - }, - - /** - * Reads and subscribes to query data anchored at the supplied data ID. The - * returned observable emits updates as the data changes over time. - */ - observe( - fragment: RelayQuery.Fragment, - dataID: DataID - ): Observable { - var fragmentPointer = new GraphQLFragmentPointer( - fragment.isPlural()? [dataID] : dataID, - fragment - ); - return new RelayQueryResultObservable(storeData, fragmentPointer); - }, - - /** - * Adds an update to the store without committing it. The returned - * RelayMutationTransaction can be committed or rolled back at a later time. - */ - applyUpdate( - mutation: RelayMutation, - callbacks?: RelayMutationTransactionCommitCallbacks - ): RelayMutationTransaction { - return storeData.getMutationQueue().createTransaction( - mutation, - callbacks - ); - }, - - /** - * Adds an update to the store and commits it immediately. Returns - * the RelayMutationTransaction. - */ - commitUpdate( - mutation: RelayMutation, - callbacks?: RelayMutationTransactionCommitCallbacks - ): RelayMutationTransaction { - const transaction = this.applyUpdate(mutation, callbacks); - transaction.commit(); - return transaction; - }, - - /** - * @deprecated - * - * Method renamed to commitUpdate - */ - update( - mutation: RelayMutation, - callbacks?: RelayMutationTransactionCommitCallbacks - ): void { - warning( - false, - '`Relay.Store.update` is deprecated. Please use' + - ' `Relay.Store.commitUpdate` or `Relay.Store.applyUpdate` instead.' - ); - this.commitUpdate(mutation, callbacks); - }, -}; - -module.exports = RelayStore; +module.exports = new RelayContext(RelayStoreData.getDefaultInstance()); diff --git a/src/store/__mocks__/RelayContext.js b/src/store/__mocks__/RelayContext.js new file mode 100644 index 0000000000000..eccb048846b33 --- /dev/null +++ b/src/store/__mocks__/RelayContext.js @@ -0,0 +1,93 @@ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +'use strict'; + +const RelayContext = jest.genMockFromModule('RelayContext'); +const RelayRecordStore = require('RelayRecordStore'); + +const resolveImmediate = require('resolveImmediate'); + +/** + * Mock object to simulate the behavior of a request. Example usage: + * + * RelayStore.primeCache(...); + * RelayStore.primeCache.mock.requests[0].block(); + * RelayStore.primeCache.mock.requests[0].fail(new Error()); + * + * A normal request should follow one of the following behaviors: + * + * block? -> resolve* -> succeed + * block? -> resolve* -> fail + * + */ +function genMockRequest(args) { + var ready = false; + return { + abort() { + args[1]({aborted: true, done: false, error: null, ready, stale: false}); + }, + block() { + args[1]({aborted: false, done: false, error: null, ready, stale: false}); + }, + resolve(config) { + var stale = config ? !!config.stale : false; + ready = true; + args[1]({aborted: false, done: false, error: null, ready, stale}); + }, + succeed() { + ready = true; + args[1]({aborted: false, done: true, error: null, ready, stale: false}); + }, + fail(error) { + args[1]({aborted: false, done: false, error, ready, stale: false}); + }, + }; +} + +RelayContext.mockImplementation(function() { + this.primeCache.mock.abort = []; + this.primeCache.mock.requests = []; + this.primeCache.mockImplementation((...args) => { + const request = genMockRequest(args); + const returnValue = { + abort: jest.genMockFunction().mockImplementation(() => { + resolveImmediate(request.abort); + }), + }; + this.primeCache.mock.abort.push(returnValue.abort); + this.primeCache.mock.requests.push(request); + return returnValue; + }); + + this.forceFetch.mock.abort = []; + this.forceFetch.mock.requests = []; + this.forceFetch.mockImplementation((...args) => { + const request = genMockRequest(args); + const returnValue = { + abort: jest.genMockFunction().mockImplementation(() => { + resolveImmediate(request.abort); + }), + }; + this.forceFetch.mock.abort.push(returnValue.abort); + this.forceFetch.mock.requests.push(request); + return returnValue; + }); + + this.mock = { + setMockRecords: records => { + this.mock.recordStore = new RelayRecordStore({records}); + }, + recordStore: null, + }; + + return this; +}); + +module.exports = RelayContext; diff --git a/src/store/__mocks__/RelayStore.js b/src/store/__mocks__/RelayStore.js index 23a4b97c649bf..6870a457391b3 100644 --- a/src/store/__mocks__/RelayStore.js +++ b/src/store/__mocks__/RelayStore.js @@ -9,81 +9,4 @@ 'use strict'; -var RelayStore = jest.genMockFromModule('RelayStore'); -const RelayRecordStore = require('RelayRecordStore'); - -const resolveImmediate = require('resolveImmediate'); - -/** - * Mock object to simulate the behavior of a request. Example usage: - * - * RelayStore.primeCache(...); - * RelayStore.primeCache.mock.requests[0].block(); - * RelayStore.primeCache.mock.requests[0].fail(new Error()); - * - * A normal request should follow one of the following behaviors: - * - * block? -> resolve* -> succeed - * block? -> resolve* -> fail - * - */ -function genMockRequest(args) { - var ready = false; - return { - abort() { - args[1]({aborted: true, done: false, error: null, ready, stale: false}); - }, - block() { - args[1]({aborted: false, done: false, error: null, ready, stale: false}); - }, - resolve(config) { - var stale = config ? !!config.stale : false; - ready = true; - args[1]({aborted: false, done: false, error: null, ready, stale}); - }, - succeed() { - ready = true; - args[1]({aborted: false, done: true, error: null, ready, stale: false}); - }, - fail(error) { - args[1]({aborted: false, done: false, error, ready, stale: false}); - }, - }; -} - -RelayStore.primeCache.mock.abort = []; -RelayStore.primeCache.mock.requests = []; -RelayStore.primeCache.mockImplementation((...args) => { - var request = genMockRequest(args); - var returnValue = { - abort: jest.genMockFunction().mockImplementation(() => { - resolveImmediate(request.abort); - }), - }; - RelayStore.primeCache.mock.abort.push(returnValue.abort); - RelayStore.primeCache.mock.requests.push(request); - return returnValue; -}); - -RelayStore.forceFetch.mock.abort = []; -RelayStore.forceFetch.mock.requests = []; -RelayStore.forceFetch.mockImplementation((...args) => { - var request = genMockRequest(args); - var returnValue = { - abort: jest.genMockFunction().mockImplementation(() => { - resolveImmediate(request.abort); - }), - }; - RelayStore.forceFetch.mock.abort.push(returnValue.abort); - RelayStore.forceFetch.mock.requests.push(request); - return returnValue; -}); - -RelayStore.mock = { - setMockRecords: records => { - RelayStore.mock.recordStore = new RelayRecordStore({records}); - }, - recordStore: null, -}; - -module.exports = RelayStore; +module.exports = require.requireActual('RelayStore'); diff --git a/src/store/__tests__/RelayStore-test.js b/src/store/__tests__/RelayContext-test.js similarity index 83% rename from src/store/__tests__/RelayStore-test.js rename to src/store/__tests__/RelayContext-test.js index 43b1cbf626076..ed37a4f593b40 100644 --- a/src/store/__tests__/RelayStore-test.js +++ b/src/store/__tests__/RelayContext-test.js @@ -11,23 +11,24 @@ 'use strict'; -jest.dontMock('RelayStore'); +jest.dontMock('RelayContext'); require('configureForRelayOSS'); const GraphQLStoreQueryResolver = require('GraphQLStoreQueryResolver'); const Relay = require('Relay'); +const RelayContext = require('RelayContext'); const RelayQueryResultObservable = require('RelayQueryResultObservable'); -const RelayStoreData = require('RelayStoreData'); const RelayMutation = require('RelayMutation'); const RelayMutationTransaction = require('RelayMutationTransaction'); const RelayMutationQueue = require('RelayMutationQueue'); +const RelayStoreData = require('RelayStoreData'); const RelayTestUtils = require('RelayTestUtils'); const readRelayQueryData = require('readRelayQueryData'); -describe('RelayStore', () => { - var RelayStore; +describe('RelayContext', () => { + var relayContext; var filter; var dataIDs; @@ -41,19 +42,20 @@ describe('RelayStore', () => { beforeEach(() => { jest.resetModuleRegistry(); - RelayStore = require('RelayStore'); + const storeData = new RelayStoreData(); + relayContext = new RelayContext(storeData); filter = () => true; dataIDs = ['feedback_id', 'likers_id']; queries = {}; callback = jest.genMockFunction(); - queryRunner = RelayStoreData.getDefaultInstance().getQueryRunner(); - recordStore = RelayStoreData.getDefaultInstance().getRecordStore(); + queryRunner = storeData.getQueryRunner(); + recordStore = storeData.getRecordStore(); }); describe('primeCache', () => { it('invokes `GraphQLQueryRunner#run`', () => { - RelayStore.primeCache(queries, callback); + relayContext.primeCache(queries, callback); expect(queryRunner.run).toBeCalled(); expect(queryRunner.run.mock.calls[0][0]).toBe(queries); @@ -63,7 +65,7 @@ describe('RelayStore', () => { describe('forceFetch', () => { it('invokes `GraphQLQueryRunner#forceFetch`', () => { - RelayStore.forceFetch(queries, callback); + relayContext.forceFetch(queries, callback); expect(queryRunner.forceFetch).toBeCalled(); expect(queryRunner.forceFetch.mock.calls[0][0]).toBe(queries); @@ -73,7 +75,7 @@ describe('RelayStore', () => { describe('read', () => { it('invokes `readRelayQueryData`', () => { - RelayStore.read(queries, dataIDs[0]); + relayContext.read(queries, dataIDs[0]); expect(readRelayQueryData).toBeCalled(); expect(readRelayQueryData.mock.calls[0][1]).toEqual(queries); expect(readRelayQueryData.mock.calls[0][2]).toBe(dataIDs[0]); @@ -81,7 +83,7 @@ describe('RelayStore', () => { }); it('invokes `readRelayQueryData` with a filter', () => { - RelayStore.read(queries, dataIDs[0], filter); + relayContext.read(queries, dataIDs[0], filter); expect(readRelayQueryData).toBeCalled(); expect(readRelayQueryData.mock.calls[0][3]).toBe(filter); }); @@ -89,7 +91,7 @@ describe('RelayStore', () => { describe('readAll', () => { it('invokes `readRelayQueryData`', () => { - RelayStore.readAll(queries, dataIDs); + relayContext.readAll(queries, dataIDs); expect(readRelayQueryData.mock.calls.length).toBe(dataIDs.length); expect(readRelayQueryData.mock.calls.map(call => call[2])).toEqual( dataIDs @@ -97,7 +99,7 @@ describe('RelayStore', () => { }); it('invokes `readRelayQueryData` with a filter', () => { - RelayStore.readAll(queries, dataIDs, filter); + relayContext.readAll(queries, dataIDs, filter); expect(readRelayQueryData.mock.calls.length).toBe(dataIDs.length); readRelayQueryData.mock.calls.forEach((call) => { expect(call[3]).toBe(filter); @@ -108,20 +110,20 @@ describe('RelayStore', () => { describe('readQuery', () => { it('accepts a query with no arguments', () => { recordStore.putDataID('viewer', null, 'client:1'); - RelayStore.readQuery(getNode(Relay.QL`query{viewer{actor{id}}}`)); + relayContext.readQuery(getNode(Relay.QL`query{viewer{actor{id}}}`)); expect(readRelayQueryData.mock.calls.length).toBe(1); expect(readRelayQueryData.mock.calls[0][2]).toBe('client:1'); }); it('accepts a query with arguments', () => { - RelayStore.readQuery(getNode(Relay.QL`query{nodes(ids:["123","456"]){id}}`)); + relayContext.readQuery(getNode(Relay.QL`query{nodes(ids:["123","456"]){id}}`)); expect(readRelayQueryData.mock.calls.length).toBe(2); expect(readRelayQueryData.mock.calls[0][2]).toBe('123'); expect(readRelayQueryData.mock.calls[1][2]).toBe('456'); }); it('accepts a query with unrecognized arguments', () => { - var result = RelayStore.readQuery(getNode(Relay.QL`query{username(name:"foo"){id}}`)); + var result = relayContext.readQuery(getNode(Relay.QL`query{username(name:"foo"){id}}`)); expect(readRelayQueryData.mock.calls.length).toBe(0); expect(result).toEqual([undefined]); }); @@ -143,7 +145,7 @@ describe('RelayStore', () => { }; }); - var observer = RelayStore.observe(fragment, '123'); + var observer = relayContext.observe(fragment, '123'); var onNext = jest.genMockFunction(); expect(observer instanceof RelayQueryResultObservable).toBe(true); observer.subscribe({onNext}); @@ -169,7 +171,8 @@ describe('RelayStore', () => { describe('applyUpdate', () => { it('creates a new RelayMutationTransaction without committing it', () => { - const transaction = RelayStore.applyUpdate(mockMutation, mockCallbacks); + const transaction = + relayContext.applyUpdate(mockMutation, mockCallbacks); expect(transaction).toEqual(mockTransaction); expect(createTransactionMock).toBeCalledWith( mockMutation, @@ -181,7 +184,7 @@ describe('RelayStore', () => { describe('commitUpdate', () => { it('creates a new RelayMutationTransaction and commits it', () => { - RelayStore.commitUpdate(mockMutation, mockCallbacks); + relayContext.commitUpdate(mockMutation, mockCallbacks); expect(createTransactionMock).toBeCalledWith( mockMutation, mockCallbacks