### Execute Queries Asynchronously and Synchronously Source: https://context7.com/tinkerbells/mobx-query/llms.txt Demonstrates how to execute queries using both asynchronous (await) and synchronous (callbacks) methods. It also shows how to check the loading, success status, and access the fetched data. ```typescript const docQuery = docsFetcher.queries.doc.create('doc-123'); // Async execution try { const data = await docQuery.async(); console.log('Document loaded:', data); } catch (error) { console.error('Failed to load:', error); } // Sync execution with callbacks docQuery.sync({ onSuccess: (data) => { console.log('Document loaded:', data); }, onError: (error) => { console.error('Failed to load:', error); }, }); // Check status console.log(docQuery.isLoading); // false console.log(docQuery.isSuccess); // true console.log(docQuery.data); // Document data ``` -------------------------------- ### Fetch Policies and Cache Configuration (TypeScript) Source: https://context7.com/tinkerbells/mobx-query/llms.txt Enables control over caching behavior using fetch policies, both globally and per-query. It illustrates 'cache-first' and 'network-only' policies, showing how they affect data retrieval. Demonstrates creating queries with specific configurations for fetching data from cache or network. Utilizes `MobxQuery` for global settings and `docsFetcher` for query-specific overrides. ```typescript // Global configuration const cacheService = new MobxQuery({ fetchPolicy: 'cache-first', enableAutoFetch: true, }); // Per-query configuration const docQuery = docsFetcher.queries.doc.createWithConfig( { fetchPolicy: 'network-only' }, 'doc-123' ); // cache-first: Return cached data if available, otherwise fetch const cachedQuery = docsFetcher.queries.doc.createWithConfig( { fetchPolicy: 'cache-first' }, 'doc-123' ); await cachedQuery.async(); // Fetches from network await cachedQuery.async(); // Returns from cache immediately // network-only: Always fetch from network, but cache the response const freshQuery = docsFetcher.queries.doc.createWithConfig( { fetchPolicy: 'network-only' }, 'doc-456' ); await freshQuery.async(); // Fetches from network await freshQuery.async(); // Fetches from network again ``` -------------------------------- ### Create InfiniteQuerySet for Paginated Lists Source: https://context7.com/tinkerbells/mobx-query/llms.txt Implements infinite scrolling for paginated lists using InfiniteQuerySet. It covers fetching the first page, loading subsequent pages with `fetchMore`, checking for the end of data, and configuring custom page sizes. ```typescript interface DocListFilters { search: string; offset: number; count: number; } const docsFetcher = { infiniteQueries: { docList: cacheService.createInfiniteQuerySet( (filters: Omit) => ({ execute: ({ offset, count }) => docsEndpoint .getDocList({ offset, count, ...filters }) .then(({ data }) => data.list), }) ), }, }; // Usage const docListQuery = docsFetcher.infiniteQueries.docList.create({ search: 'test' }); // Load first page await docListQuery.async(); console.log(docListQuery.data.length); // 30 records // Load next page docListQuery.fetchMore(); await when(() => !docListQuery.isLoading); console.log(docListQuery.data.length); // 60 records // Check if all data loaded if (docListQuery.isEndReached) { console.log('No more data to load'); } // Custom page size const customQuery = docsFetcher.infiniteQueries.docList.createWithConfig( { incrementCount: 50 }, { search: 'test' } ); ``` -------------------------------- ### Test MobX Query Store with Mock Fetcher in TypeScript Source: https://context7.com/tinkerbells/mobx-query/llms.txt This snippet demonstrates how to test a MobX Query store using a mock fetcher in TypeScript. It involves creating an isolated MobxQuery instance, defining mock query data, instantiating the store with the mock fetcher, and asserting the formatted output after data fetching is complete. This ensures store logic works as expected without external dependencies. ```typescript import { when } from 'mobx'; import { MobxQuery } from '@tinkerbells/mobx-query'; type Fetcher = { queries: Record>; infiniteQueries: Record>; mutations: Record>; }; const mockFetcher = (config: DeepPartial) => config as TFetcher; describe('BooksListStore', () => { it('formats book list for display', async () => { // Create isolated MobxQuery instance per test const mobxQuery = new MobxQuery({ enabledAutoFetch: true }); const fakeBookList = [ { id: '1', name: 'Book 1', price: 1000 }, { id: '2', name: 'Book 2', price: 2000 }, ]; const booksFetcherMock = mockFetcher({ queries: { bookList: mobxQuery.createQuerySet(() => ({ execute: async () => fakeBookList, })), }, }); const sut = new BooksListStore(booksFetcherMock); // Wait for auto-fetch to complete await when(() => Boolean(sut.list?.length)); expect(sut.list[0]).toEqual({ id: '1', name: 'Book 1', price: '1 000 руб.', }); }); }); ``` -------------------------------- ### Background Data Updates with Background Mode (TypeScript) Source: https://context7.com/tinkerbells/mobx-query/llms.txt Facilitates fetching data without blocking the UI by utilizing a background mode. It shows how to initiate a query in the background, update UI elements based on initial states, and then display the updated data once the background fetch is complete. This approach prevents UI freezes during data refetching after invalidation. Uses `docsFetcher` and `when` from an observability library. ```typescript const docQuery = docsFetcher.queries.doc.createWithConfig( { isBackground: true }, 'doc-123' ); docQuery.sync(); // First request changes main status flags console.log(docQuery.isLoading); // true await when(() => docQuery.isSuccess); // Invalidate and refetch in background docsFetcher.queries.doc.invalidate(); console.log(docQuery.isLoading); // false - UI not blocked console.log(docQuery.background.isLoading); // true - fetching in background console.log(docQuery.data); // Still shows old data await when(() => !docQuery.background.isLoading); console.log(docQuery.data); // Now shows updated data ``` -------------------------------- ### Initialize MobxQuery Cache Service Source: https://context7.com/tinkerbells/mobx-query/llms.txt Initializes the MobxQuery cache service with configuration options for automatic fetching and cache policy. This is the first step in setting up the library for managing server state. ```typescript import { MobxQuery } from '@tinkerbells/mobx-query'; export const cacheService = new MobxQuery({ enableAutoFetch: true, fetchPolicy: 'cache-first' }); ``` -------------------------------- ### Core Query API Usage - TypeScript Source: https://context7.com/tinkerbells/mobx-query/llms.txt Utilize the low-level query creation API for custom implementations. This allows direct creation of queries with specified keys, fetch functions, and configuration options such as fetch policies and error handling. It also provides methods for executing, invalidating, and checking query status. ```typescript // Direct query creation without QuerySet const docQuery = cacheService.createQuery( ['doc', 'doc-123'], () => docsEndpoints.getDoc('doc-123'), { enabledAutoFetch: true, fetchPolicy: 'cache-first', onError: (error) => console.error('Query failed:', error), } ); // Access data console.log(docQuery.data); console.log(docQuery.isLoading); console.log(docQuery.isSuccess); console.log(docQuery.isError); console.log(docQuery.error); // Execute query await docQuery.async(); // Invalidate docQuery.invalidate(); // Background status console.log(docQuery.background.isLoading); console.log(docQuery.background.isError); console.log(docQuery.background.error); ``` -------------------------------- ### Create MutationSet for Data Mutations (TypeScript) Source: https://context7.com/tinkerbells/mobx-query/llms.txt Handles data mutations with automatic state management using `createMutationSet`. It defines mutation operations like `editDoc` and `createDoc` and demonstrates their usage within a store for saving documents. Supports both asynchronous and synchronous updates with success and error callbacks. Requires `cacheService` and `docsEndpoints` to be defined. ```typescript interface EditDocInput { id: string; name: string; content: string; } const docsFetcher = { mutations: { editDoc: cacheService.createMutationSet( (params: EditDocInput) => docsEndpoints.editDoc(params) ), createDoc: cacheService.createMutationSet( (params: Omit) => docsEndpoints.createDoc(params) ), }, }; // Usage in store class DocEditorStore { private readonly editMutation; constructor(private readonly _fetcher: typeof docsFetcher) { this.editMutation = this._fetcher.mutations.editDoc.create(); } public async saveDocument(id: string, name: string, content: string) { try { await this.editMutation.async({ id, name, content }); console.log('Document saved successfully'); } catch (error) { console.error('Failed to save:', error); } } // Sync version with callbacks public saveDocumentSync(id: string, name: string, content: string) { this.editMutation.sync({ params: { id, name, content }, onSuccess: (data) => console.log('Saved:', data), onError: (error) => console.error('Error:', error), }); } public get isSaving() { return this.editMutation.isLoading; } } ``` -------------------------------- ### Create QuerySet for Entity Data Fetching Source: https://context7.com/tinkerbells/mobx-query/llms.txt Defines a QuerySet for fetching individual entity data with automatic caching. It supports custom cache keys and demonstrates usage within a MobX store, including reactive data access and loading status. ```typescript const docsFetcher = { queries: { doc: cacheService.createQuerySet((id: string) => ({ execute: () => docsEndpoints.getDoc(id).then(({ data }) => data), })), docWithFilters: cacheService.createQuerySet((id: string, filters: { search: string }) => ({ keys: [id], // Custom cache keys - only id will be used for caching execute: () => docsEndpoints.getDoc(id, filters).then(({ data }) => data), })), }, }; // Usage in store class DocStore { constructor(private readonly _docID: string, private readonly _docsFetcher: typeof docsFetcher) { makeAutoObservable(this, {}, { autoBind: true }); } private get docQuery() { return this._docsFetcher.queries.doc.create(this._docID); } public get docName() { if (!this.docQuery.data) return ''; return `Document: ${this.docQuery.data.name}`; } public get isLoading() { return this.docQuery.isLoading; } } ``` -------------------------------- ### Core InfiniteQuery API Usage - TypeScript Source: https://context7.com/tinkerbells/mobx-query/llms.txt Implement custom pagination logic using the low-level infinite query API. This enables defining how data is fetched in chunks and provides methods to load more data, check if the end of the data has been reached, and invalidate/reset the query. ```typescript const docListQuery = cacheService.createInfiniteQuery( ['docList', { search: 'test' }], ({ offset, count }) => docsEndpoint.getDocList({ offset, count, search: 'test' }).then(({ data }) => data.list), { incrementCount: 30, enabledAutoFetch: true, fetchPolicy: 'cache-first', } ); // Load data await docListQuery.async(); console.log(docListQuery.data); // Array of items // Load more docListQuery.fetchMore(); // Check end console.log(docListQuery.isEndReached); // Invalidate and reset docListQuery.invalidate(); ``` -------------------------------- ### Core Mutation API Usage - TypeScript Source: https://context7.com/tinkerbells/mobx-query/llms.txt Manage data modifications through the low-level mutation API. This allows for the creation of mutations with defined execution functions and options for handling success and error states. Mutations can be executed asynchronously or synchronously with callbacks. ```typescript const editDocMutation = cacheService.createMutation( (params) => docsEndpoints.editDoc(params), { onError: (error) => console.error('Mutation failed:', error), } ); // Execute mutation await editDocMutation.async({ id: 'doc-123', name: 'Updated', content: 'New content' }); // Sync execution editDocMutation.sync({ params: { id: 'doc-123', name: 'Updated', content: 'New content' }, onSuccess: (data) => console.log('Success:', data), onError: (error) => console.error('Error:', error), }); // Check status console.log(editDocMutation.isLoading); console.log(editDocMutation.isSuccess); console.log(editDocMutation.isError); console.log(editDocMutation.error); ``` -------------------------------- ### Enable Tab Synchronization - TypeScript Source: https://context7.com/tinkerbells/mobx-query/llms.txt Synchronize cache data across different browser tabs in real-time. This feature ensures that data updates in one tab are automatically reflected in other open tabs, which is particularly useful for applications requiring real-time collaboration. ```typescript // Enable globally const cacheService = new MobxQuery({ enabledSynchronization: true, }); // Enable per-query const docQuery = docsFetcher.queries.doc.createWithConfig( { enabledSynchronization: true }, 'doc-123' ); // When data updates in one tab, all other tabs automatically receive the update // Useful for real-time collaboration features ``` -------------------------------- ### Cache Invalidation for Queries (TypeScript) Source: https://context7.com/tinkerbells/mobx-query/llms.txt Provides mechanisms to invalidate cached data globally or with partial key matching. It demonstrates how to invalidate specific queries by ID or with object matching, as well as global invalidation of all queries or low-level invalidation using cache keys. Relies on `cacheService` and `docsFetcher` configurations. ```typescript const docsFetcher = { queries: { doc: cacheService.createQuerySet((id: string, filters: { sort: string }) => ({ execute: () => docsEndpoints.getDoc(id, filters), })), }, }; const query1 = docsFetcher.queries.doc.create('1', { sort: 'asc' }); const query2 = docsFetcher.queries.doc.create('2', { sort: 'desc' }); // Invalidate all doc queries docsFetcher.queries.doc.invalidate(); // Invalidate specific doc by id docsFetcher.queries.doc.invalidate('1'); // Invalidate with partial object match docsFetcher.queries.doc.invalidate('1', { sort: 'asc' }); // Global invalidation of all queries cacheService.invalidateQueries(); // Low-level invalidation by cache keys cacheService.invalidate(['users', '1'], 'partial-match'); cacheService.invalidate(['users', '1'], 'chain-match'); ``` -------------------------------- ### Set Up Polling for Cache Invalidation - TypeScript Source: https://context7.com/tinkerbells/mobx-query/llms.txt Configure periodic cache invalidation to ensure data is consistently fresh. This involves setting a polling interval for queries, after which the data will be automatically refetched from the server. Supports both regular and infinite queries. ```typescript const TEN_MINUTES = 10 * 60 * 1000; // Query with polling const docQuery = docsFetcher.queries.doc.createWithConfig( { pollingTime: TEN_MINUTES }, 'doc-123' ); // Infinite query with polling const docListQuery = docsFetcher.infiniteQueries.docList.createWithConfig( { pollingTime: TEN_MINUTES }, { search: 'test' } ); // Data will be automatically invalidated and refetched every 10 minutes ``` -------------------------------- ### Force Update Cache Data - TypeScript Source: https://context7.com/tinkerbells/mobx-query/llms.txt Manually update cached data for a specific query or a set of queries without initiating network requests. This method allows direct data setting or updating via a function that receives current data. It supports batch updates for multiple queries. ```typescript const docQuery = docsFetcher.queries.doc.create('doc-123'); // Set data directly docQuery.forceUpdate({ name: 'Updated Document', content: 'New content' }); console.log(docQuery.data); // { name: 'Updated Document', content: 'New content' } console.log(docQuery.isSuccess); // true // Update with function docQuery.forceUpdate((currentData) => ({ ...currentData, name: currentData.name + ' (edited)', })); // Batch update multiple queries const docsFetcher = { queries: { docsList: cacheService.createQuerySet((userId: string, filters?: object) => ({ execute: () => docsEndpoints.getDocsList(userId, filters), })), }, }; const queryA = docsFetcher.queries.docsList.create('user-1'); const queryB = docsFetcher.queries.docsList.create('user-1', { isDesc: true }); // Update all matching queries docsFetcher.queries.docsList.forceUpdate( (currentData = []) => [...currentData, { id: 'new-doc', name: 'New Document' }], 'user-1' ); console.log(queryA.data); // Contains new document console.log(queryB.data); // Contains new document ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.