diff --git a/examples/basic/package.json b/examples/basic/package.json index 507ec78..ace28ef 100644 --- a/examples/basic/package.json +++ b/examples/basic/package.json @@ -13,7 +13,7 @@ "mobx": "6.13.5", "mobx-react": "9.1.1", "mobx-state-tree": "6.0.1", - "mst-query": "4.0.1" + "mst-query": "4.0.2" }, "devDependencies": { "@types/react": "^18.2.79", diff --git a/examples/table-filters/index.html b/examples/table-filters/index.html index 47dffa5..1b3ea70 100644 --- a/examples/table-filters/index.html +++ b/examples/table-filters/index.html @@ -8,6 +8,6 @@
- + diff --git a/examples/table-filters/package-lock.json b/examples/table-filters/package-lock.json index efec55c..bd0916f 100644 --- a/examples/table-filters/package-lock.json +++ b/examples/table-filters/package-lock.json @@ -9,7 +9,7 @@ "mobx": "6.13.5", "mobx-react": "9.1.1", "mobx-state-tree": "6.0.1", - "mst-query": "4.0.1", + "mst-query": "4.0.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.4.2" @@ -1397,9 +1397,9 @@ "dev": true }, "node_modules/mst-query": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/mst-query/-/mst-query-4.0.1.tgz", - "integrity": "sha512-4xUyq34urgAoeA0punlIDAp0tmg4QTZGDYPVx9oopg6560FjjykIQJgQGt8QqmE+Ie7e6sDkR+rfSvGdVMdSpA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/mst-query/-/mst-query-4.0.2.tgz", + "integrity": "sha512-f2i7vtSrrHBWan2yBKtatGcaXjEUSv1PYBL0JgyqRqgbTYTDaX8YkXoeUB1WpKCwonIsNDYPGvzKQM2PfsjG+w==", "dependencies": { "@wry/equality": "0.5.7" }, diff --git a/examples/table-filters/package.json b/examples/table-filters/package.json index dc22fad..01c1d52 100644 --- a/examples/table-filters/package.json +++ b/examples/table-filters/package.json @@ -11,7 +11,7 @@ "mobx": "6.13.5", "mobx-react": "9.1.1", "mobx-state-tree": "6.0.1", - "mst-query": "4.0.1", + "mst-query": "4.0.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.4.2" diff --git a/examples/table-filters/src/components/App.tsx b/examples/table-filters/src/components/App.tsx index 80cd174..3ac3db2 100644 --- a/examples/table-filters/src/components/App.tsx +++ b/examples/table-filters/src/components/App.tsx @@ -1,51 +1,49 @@ -import { observer } from "mobx-react"; -import { useQuery } from "mst-query"; -import { useEffect } from "react"; -import { Link, Outlet, useNavigate, useParams } from "react-router-dom"; -import { useRootStore } from "../context"; -import { CompanyModelType } from "../models/models"; +import { observer } from 'mobx-react'; +import { useQuery } from 'mst-query'; +import { useEffect } from 'react'; +import { Link, Outlet, useNavigate, useParams } from 'react-router-dom'; +import { useRootStore } from '../context'; +import { CompanyModelType } from '../models/models'; const Sidebar = observer(({ items }: { items: CompanyModelType[] }) => { - const { companyId } = useParams(); - const navigate = useNavigate(); + const { companyId } = useParams(); + const navigate = useNavigate(); - useEffect(() => { - if (!companyId && items.length) { - navigate(`/company/${items[0].id}`); - } - }, [companyId, items, navigate]); + useEffect(() => { + if (!companyId && items.length) { + navigate(`/company/${items[0].id}`); + } + }, [companyId, items, navigate]); - return ( -
- {items.map((item: any) => ( -
- {item.name} + return ( +
+ {items.map((item: any) => ( +
+ {item.name} +
+ ))}
- ))} -
- ); + ); }); -const MainScreen = observer( - ({ companies }: { companies: CompanyModelType[] }) => { +const MainScreen = observer(({ companies }: { companies: CompanyModelType[] }) => { return ( -
-
- +
+
+ +
+
+ +
-
- -
-
); - }, -); +}); export const App = observer(() => { - const rootStore = useRootStore(); - const { data } = useQuery(rootStore.baseQuery); - if (!data) { - return
Loading app...
; - } - return ; + const rootStore = useRootStore(); + const { data } = useQuery(rootStore.baseQuery); + if (!data) { + return
Loading app...
; + } + return ; }); diff --git a/examples/table-filters/src/components/InvoiceList.tsx b/examples/table-filters/src/components/InvoiceList.tsx index 37781e5..8cb4406 100644 --- a/examples/table-filters/src/components/InvoiceList.tsx +++ b/examples/table-filters/src/components/InvoiceList.tsx @@ -1,180 +1,177 @@ -import { observer } from "mobx-react"; -import { useState } from "react"; -import { useParams, useSearchParams } from "react-router-dom"; -import { useQuery, useMutation } from "mst-query"; -import { useRootStore } from "../context"; -import { InvoiceModelType, InvoiceFilterModelType } from "../models/models"; -import { InvoiceEditor } from "./InvoicePreview"; -import { InvoiceListFilters } from "./InvoiceListFilters"; +import { observer } from 'mobx-react'; +import { useState } from 'react'; +import { useParams, useSearchParams } from 'react-router-dom'; +import { useMutation, useInfiniteQuery } from 'mst-query'; +import { useRootStore } from '../context'; +import { InvoiceModelType, InvoiceFilterModelType } from '../models/models'; +import { InvoiceEditor } from './InvoicePreview'; +import { InvoiceListFilters } from './InvoiceListFilters'; const List = observer( - (props: { - items: InvoiceModelType[]; - onRowClick: (item: InvoiceModelType) => void; - minAmount: number; - selectedItemId?: string; - }) => { - const { items, minAmount, onRowClick, selectedItemId } = props; - return ( - <> - {items - .filter((invoice) => invoice.amount > minAmount) - .map((invoice) => ( - onRowClick(invoice)} - style={{ - background: selectedItemId === invoice.id ? "#eee" : undefined - }} - > - {invoice.id} - {invoice.amount} - {invoice.createdBy.shortName} - - ))} - - ); - } + (props: { + items: InvoiceModelType[]; + onRowClick: (item: InvoiceModelType) => void; + minAmount: number; + selectedItemId?: string; + }) => { + const { items, minAmount, onRowClick, selectedItemId } = props; + return ( + <> + {items + .filter((invoice) => invoice.amount > minAmount) + .map((invoice) => ( + onRowClick(invoice)} + style={{ + background: selectedItemId === invoice.id ? '#eee' : undefined, + }}> + {invoice.id} + {invoice.amount} + {invoice.createdBy.shortName} + + ))} + + ); + } ); export const InvoiceList = observer(() => { - const rootStore = useRootStore(); - const invoiceService = rootStore.invoiceService; - const invoiceStore = rootStore.invoiceStore; + const rootStore = useRootStore(); + const invoiceService = rootStore.invoiceService; + const invoiceStore = rootStore.invoiceStore; - const { companyId } = useParams(); - const [searchParams, setSearchParams] = useSearchParams(); - const [offset, setOffset] = useState(0); - const [previewId, setPreviewId] = useState(); + const { companyId } = useParams(); + const [searchParams, setSearchParams] = useSearchParams(); + const [offset, setOffset] = useState(0); + const [previewId, setPreviewId] = useState(); - const { data, isLoading, isFetchingMore, isRefetching, refetch } = useQuery( - invoiceService.invoiceListQuery, - { - request: { id: companyId! }, - pagination: { offset } - } - ); + const { data, isLoading, isFetchingMore, isRefetching, refetch } = useInfiniteQuery( + invoiceService.invoiceListQuery, + { + request: { id: companyId! }, + pagination: { offset }, + } + ); - const [remove] = useMutation(invoiceService.removeInvoiceFilterMutation); - const [save] = useMutation(invoiceService.saveInvoiceFilterMutation); + const [remove] = useMutation(invoiceService.removeInvoiceFilterMutation); + const [save] = useMutation(invoiceService.saveInvoiceFilterMutation); - const selectedFilter = - data?.filters.find((filter) => filter.id === searchParams.get("filter")) ?? - data?.filters[0]; - const preview = previewId && invoiceStore.models.get(previewId); + const selectedFilter = + data?.filters.find((filter) => filter.id === searchParams.get('filter')) ?? + data?.filters[0]; + const preview = previewId && invoiceStore.models.get(previewId); - const handleOnSelectedFilter = (filter: InvoiceFilterModelType) => { - setSearchParams({ filter: filter.id }); - }; + const handleOnSelectedFilter = (filter: InvoiceFilterModelType) => { + setSearchParams({ filter: filter.id }); + }; - const saveFilter = async (filter: InvoiceFilterModelType) => { - const result = await save({ - request: { id: filter.id, filter: filter.filter ?? "" } - }); - if (result.data) { - setSearchParams({ filter: result.data?.id }); - } - }; + const saveFilter = async (filter: InvoiceFilterModelType) => { + const result = await save({ + request: { id: filter.id, filter: filter.filter ?? '' }, + }); + if (result.data) { + setSearchParams({ filter: result.data?.id }); + } + }; - const addFilter = async () => { - const result = await save({ - request: { id: undefined, filter: "" } - }); - if (result.data) { - setSearchParams({ filter: result.data.id }); - } - }; + const addFilter = async () => { + const result = await save({ + request: { id: undefined, filter: '' }, + }); + if (result.data) { + setSearchParams({ filter: result.data.id }); + } + }; - const removeFilter = async (filter: InvoiceFilterModelType) => { - await remove({ request: { id: filter.id } }); - if (data?.filters.length) { - setSearchParams({ filter: data.filters[0].id }); - } - }; + const removeFilter = async (filter: InvoiceFilterModelType) => { + await remove({ request: { id: filter.id } }); + if (data?.filters.length) { + setSearchParams({ filter: data.filters[0].id }); + } + }; - const loadMore = () => { - const offset = (data?.invoices.length ?? 0) + 1; - setOffset(offset); - }; + const loadMore = () => { + const offset = (data?.invoices.length ?? 0) + 1; + setOffset(offset); + }; - const reset = () => { - setOffset(0); - refetch({ request: { id: companyId }, pagination: { offset: 0 } }); - }; + const reset = () => { + setOffset(0); + refetch({ request: { id: companyId }, pagination: { offset: 0 } }); + }; - if (!data || !selectedFilter) { - return
Loading invoices...
; - } - return ( -
-
- -
-
- - - - - - - -
-
-
isLoading:{`${isLoading}`}
-
isRefetching:{`${isRefetching}`}
-
isFetchingMore:{`${isFetchingMore}`}
-
-
-
- - - - - - - - - - - setPreviewId((id) => (id === item.id ? undefined : item.id)) - } - selectedItemId={previewId} - /> - -
Invoice idAmountCreated by
-
-
- {preview && } + if (!data || !selectedFilter) { + return
Loading invoices...
; + } + return ( +
+
+ +
+
+ + + + + + + +
+
+
isLoading:{`${isLoading}`}
+
isRefetching:{`${isRefetching}`}
+
isFetchingMore:{`${isFetchingMore}`}
+
+
+
+ + + + + + + + + + + setPreviewId((id) => (id === item.id ? undefined : item.id)) + } + selectedItemId={previewId} + /> + +
Invoice idAmountCreated by
+
+
+ {preview && } +
+
-
-
- ); + ); }); diff --git a/examples/table-filters/src/models/stores.ts b/examples/table-filters/src/models/stores.ts index 64e4d7b..31b6a00 100644 --- a/examples/table-filters/src/models/stores.ts +++ b/examples/table-filters/src/models/stores.ts @@ -1,44 +1,28 @@ -import { flow, types, Instance } from 'mobx-state-tree'; +import { types, Instance } from 'mobx-state-tree'; import { createModelStore, createRootStore } from 'mst-query'; -import { InvoiceApiStore, InvoiceApiStoreType } from './api'; +import { InvoiceService } from './services'; import { InvoiceFilterModel, InvoiceModel, CompanyModel, UserModel } from './models'; -import { AppQuery, AppQueryType } from './queries'; +import { AppQuery } from './queries'; -export const InvoiceModelStore = createModelStore(InvoiceModel); -type InvoiceModelStoreType = Instance; +export const InvoiceModelStore = createModelStore('InvoiceModelStore', InvoiceModel); -export const InvoiceFilterModelStore = createModelStore(InvoiceFilterModel); -type InvoiceFilterModelStoreType = Instance; +export const InvoiceFilterModelStore = createModelStore( + 'InvoiceFilterModelStore', + InvoiceFilterModel +); -export const CompanyModelStore = createModelStore(CompanyModel); -type CompanyModelStoreType = Instance; +export const CompanyModelStore = createModelStore('CompanyModelStore', CompanyModel); -export const UserModelStore = createModelStore(UserModel); -type UserModelStoreType = Instance; +export const UserModelStore = createModelStore('UserModelStore', UserModel); export const RootStore = createRootStore({ invoiceStore: types.optional(InvoiceModelStore, {}), invoiceFilterStore: types.optional(InvoiceFilterModelStore, {}), companyStore: types.optional(CompanyModelStore, {}), userStore: types.optional(UserModelStore, {}), -}) - .props({ - invoiceApiStore: types.optional(InvoiceApiStore, {}), - baseQuery: types.optional(AppQuery, {}), - }) - .actions((self) => ({ - getBase: flow(function* () { - const next = yield* self.baseQuery.query(); - next(); - }) - })); +}).props({ + invoiceService: types.optional(InvoiceService, {}), + baseQuery: types.optional(AppQuery, {}), +}); -export type RootStoreType = { - invoiceStore: InvoiceModelStoreType; - invoiceFilterStore: InvoiceFilterModelStoreType; - companyStore: CompanyModelStoreType; - userStore: UserModelStoreType; - invoiceApiStore: InvoiceApiStoreType; - baseQuery: AppQueryType; - getBase: () => Promise; -}; +export type RootStoreType = Instance; diff --git a/packages/mst-query/package-lock.json b/packages/mst-query/package-lock.json index d6d414c..2f76550 100644 --- a/packages/mst-query/package-lock.json +++ b/packages/mst-query/package-lock.json @@ -1,12 +1,12 @@ { "name": "mst-query", - "version": "4.0.1", + "version": "4.0.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mst-query", - "version": "4.0.1", + "version": "4.0.2", "license": "MIT", "dependencies": { "@wry/equality": "0.5.7" diff --git a/packages/mst-query/package.json b/packages/mst-query/package.json index a2b8f05..46b816f 100644 --- a/packages/mst-query/package.json +++ b/packages/mst-query/package.json @@ -1,6 +1,6 @@ { "name": "mst-query", - "version": "4.0.1", + "version": "4.0.2", "description": "Query library for mobx-state-tree", "source": "src/index.ts", "type": "module", diff --git a/packages/mst-query/src/create.ts b/packages/mst-query/src/create.ts index 522e29e..dfc4899 100644 --- a/packages/mst-query/src/create.ts +++ b/packages/mst-query/src/create.ts @@ -100,6 +100,7 @@ export function createQuery( .volatile((self) => ({ __MstQueryHandler: new MstQueryHandler(self, { endpoint }), isQuery: true, + isInfinte: false, isMutation: false, })) .views((self) => ({ @@ -173,6 +174,7 @@ export function createInfiniteQuery< .volatile((self) => ({ __MstQueryHandler: new MstQueryHandler(self, { endpoint, onQueryMore }), isQuery: true, + isInfinite: true, isMutation: false, })) .views((self) => ({ @@ -255,6 +257,7 @@ export function createMutation ({ __MstQueryHandler: new MstQueryHandler(self, { endpoint }), isQuery: false, + isInfinte: false, isMutation: true, })) .views((self) => ({ diff --git a/packages/mst-query/src/hooks.ts b/packages/mst-query/src/hooks.ts index 570140b..e66f5e1 100644 --- a/packages/mst-query/src/hooks.ts +++ b/packages/mst-query/src/hooks.ts @@ -35,7 +35,7 @@ export function useQuery>( (options as any).request = options.request ?? EmptyRequest; - if ((query as any).variables.pagination) { + if ((query as any).isInfinite) { throw new Error('useQuery should be used with a query that does not have pagination. Use useInfiniteQuery instead.'); } @@ -91,7 +91,7 @@ export function useInfiniteQuery>( (options as any).request = options.request ?? EmptyRequest; (options as any).pagination = options.pagination ?? EmptyPagination; - if (!(query as any).variables.pagination) { + if (!(query as any).isInfinite) { throw new Error('useInfiniteQuery should be used with a query that has pagination. Use useQuery instead.'); }