@ui-construction-library/integration-tanstack-query 0.1.5 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/QueryBoundary.d.ts +27 -0
  2. package/dist/QueryBoundary.d.ts.map +1 -0
  3. package/dist/QueryList.d.ts +42 -0
  4. package/dist/QueryList.d.ts.map +1 -0
  5. package/dist/QueryTable.d.ts +46 -0
  6. package/dist/QueryTable.d.ts.map +1 -0
  7. package/dist/index.d.ts +7 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.esm.js +127 -4
  10. package/dist/index.esm.js.map +1 -1
  11. package/dist/index.js +126 -0
  12. package/dist/index.js.map +1 -1
  13. package/package.json +31 -12
  14. package/.rollup.cache/Users/jilimbo/Documents/PersonalProjects/UI-Library/packages/integrations/tanstack-query/dist/index.d.ts +0 -19
  15. package/.rollup.cache/Users/jilimbo/Documents/PersonalProjects/UI-Library/packages/integrations/tanstack-query/dist/index.d.ts.map +0 -1
  16. package/.rollup.cache/Users/jilimbo/Documents/PersonalProjects/UI-Library/packages/integrations/tanstack-query/dist/index.js +0 -12
  17. package/.rollup.cache/Users/jilimbo/Documents/PersonalProjects/UI-Library/packages/integrations/tanstack-query/dist/index.js.map +0 -1
  18. package/.rollup.cache/Users/jilimbo/Documents/PersonalProjects/UI-Library/packages/integrations/tanstack-query/dist/index.test.d.ts +0 -2
  19. package/.rollup.cache/Users/jilimbo/Documents/PersonalProjects/UI-Library/packages/integrations/tanstack-query/dist/index.test.d.ts.map +0 -1
  20. package/.rollup.cache/Users/jilimbo/Documents/PersonalProjects/UI-Library/packages/integrations/tanstack-query/dist/index.test.js +0 -37
  21. package/.rollup.cache/Users/jilimbo/Documents/PersonalProjects/UI-Library/packages/integrations/tanstack-query/dist/index.test.js.map +0 -1
  22. package/.rollup.cache/Users/jilimbo/Documents/PersonalProjects/UI-Library/packages/integrations/tanstack-query/tsconfig.tsbuildinfo +0 -1
  23. package/.turbo/turbo-build.log +0 -6
  24. package/.turbo/turbo-test.log +0 -12
  25. package/.turbo/turbo-typecheck.log +0 -2
  26. package/CHANGELOG.md +0 -159
  27. package/rollup.config.js +0 -18
  28. package/src/index.test.tsx +0 -62
  29. package/src/index.tsx +0 -33
  30. package/tsconfig.json +0 -22
  31. package/tsconfig.tsbuildinfo +0 -1
  32. package/ui-construction-library-integration-tanstack-query-0.1.1.tgz +0 -0
  33. package/ui-construction-library-integration-tanstack-query-0.1.2.tgz +0 -0
  34. package/ui-construction-library-integration-tanstack-query-0.1.3.tgz +0 -0
@@ -0,0 +1,27 @@
1
+ import { type QueryKey } from '@tanstack/react-query';
2
+ import type { ReactNode } from 'react';
3
+ export type QueryBoundaryProps = {
4
+ /** Content rendered while the query is loading (shown inside `<Suspense>`). */
5
+ loadingFallback?: ReactNode;
6
+ /** Content or render function shown when the query throws an error. */
7
+ errorFallback?: ReactNode | ((error: Error, retry: () => void) => ReactNode);
8
+ /** Optional query key — when provided, `retry` invalidates the query before re-rendering. */
9
+ queryKey?: QueryKey;
10
+ children: ReactNode;
11
+ };
12
+ /**
13
+ * Wraps query-consuming children with `Suspense` + an error boundary.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * <QueryBoundary
18
+ * loadingFallback={<Skeleton />}
19
+ * errorFallback={(err, retry) => <div>Failed: {err.message} <button onClick={retry}>Retry</button></div>}
20
+ * queryKey={['users']}
21
+ * >
22
+ * <UsersList />
23
+ * </QueryBoundary>
24
+ * ```
25
+ */
26
+ export declare function QueryBoundary({ loadingFallback, errorFallback, queryKey, children, }: QueryBoundaryProps): import("react/jsx-runtime").JSX.Element;
27
+ //# sourceMappingURL=QueryBoundary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBoundary.d.ts","sourceRoot":"","sources":["../src/QueryBoundary.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,uBAAuB,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAuDvC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,+EAA+E;IAC/E,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,uEAAuE;IACvE,aAAa,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,SAAS,CAAC,CAAC;IAC7E,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,EAC5B,eAA2D,EAC3D,aAAa,EACb,QAAQ,EACR,QAAQ,GACT,EAAE,kBAAkB,2CA4BpB"}
@@ -0,0 +1,42 @@
1
+ import { type QueryKey } from '@tanstack/react-query';
2
+ import type { ReactNode } from 'react';
3
+ export type QueryListPage<T> = {
4
+ items: T[];
5
+ nextCursor?: string | number | null;
6
+ };
7
+ export type QueryListProps<T> = {
8
+ /** TanStack Query cache key. */
9
+ queryKey: QueryKey;
10
+ /** Paginated fetch — receives `{ pageParam }` and returns one page. */
11
+ queryFn: (ctx: {
12
+ pageParam?: string | number;
13
+ }) => Promise<QueryListPage<T>>;
14
+ /** Render function for a single item. */
15
+ renderItem: (item: T, index: number) => ReactNode;
16
+ /** Custom loading placeholder. */
17
+ loadingFallback?: ReactNode;
18
+ /** Custom error state. */
19
+ errorFallback?: ReactNode | ((error: Error) => ReactNode);
20
+ /** Custom empty state. */
21
+ emptyFallback?: ReactNode;
22
+ /** Label for the "Load more" button. */
23
+ loadMoreLabel?: string;
24
+ /** Number of skeleton items shown while loading (default 3). */
25
+ skeletonRows?: number;
26
+ };
27
+ /**
28
+ * Infinite-scroll / load-more list backed by TanStack Query's `useInfiniteQuery`.
29
+ *
30
+ * @example
31
+ * ```tsx
32
+ * <QueryList<User>
33
+ * queryKey={['users-list']}
34
+ * queryFn={({ pageParam }) =>
35
+ * fetch(`/api/users?cursor=${pageParam ?? ''}`).then(r => r.json())
36
+ * }
37
+ * renderItem={(user) => <div>{user.name}</div>}
38
+ * />
39
+ * ```
40
+ */
41
+ export declare function QueryList<T>({ queryKey, queryFn, renderItem, loadingFallback, errorFallback, emptyFallback, loadMoreLabel, skeletonRows, }: QueryListProps<T>): string | number | boolean | Iterable<ReactNode> | import("react/jsx-runtime").JSX.Element;
42
+ //# sourceMappingURL=QueryList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryList.d.ts","sourceRoot":"","sources":["../src/QueryList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAoB,MAAM,uBAAuB,CAAC;AAExE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAC7B,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,gCAAgC;IAChC,QAAQ,EAAE,QAAQ,CAAC;IACnB,uEAAuE;IACvE,OAAO,EAAE,CAAC,GAAG,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,yCAAyC;IACzC,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC;IAClD,kCAAkC;IAClC,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,0BAA0B;IAC1B,aAAa,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC;IAC1D,0BAA0B;IAC1B,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,wCAAwC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAC3B,QAAQ,EACR,OAAO,EACP,UAAU,EACV,eAAe,EACf,aAAa,EACb,aAAa,EACb,aAA2B,EAC3B,YAAgB,GACjB,EAAE,cAAc,CAAC,CAAC,CAAC,6FA+EnB"}
@@ -0,0 +1,46 @@
1
+ import { type QueryKey } from '@tanstack/react-query';
2
+ import type { ReactNode } from 'react';
3
+ type Column<T> = {
4
+ key: string;
5
+ header: string;
6
+ width?: number | string;
7
+ sortable?: boolean;
8
+ filterable?: boolean;
9
+ render?: (item: T) => ReactNode;
10
+ };
11
+ export type QueryTableProps<T> = {
12
+ /** TanStack Query cache key. */
13
+ queryKey: QueryKey;
14
+ /** Function that fetches the row data. */
15
+ queryFn: () => Promise<T[]>;
16
+ /** Column definitions passed to `DataTable`. */
17
+ columns: Column<T>[];
18
+ /** Page size passed to `DataTable`. */
19
+ pageSize?: number;
20
+ /** Custom loading placeholder. */
21
+ loadingFallback?: ReactNode;
22
+ /** Custom error state. */
23
+ errorFallback?: ReactNode | ((error: Error) => ReactNode);
24
+ /** Custom empty state shown when `data.length === 0`. */
25
+ emptyFallback?: ReactNode;
26
+ /** Number of skeleton rows to show while loading (default 5). */
27
+ skeletonRows?: number;
28
+ };
29
+ /**
30
+ * Data table pre-wired with TanStack Query loading, error and empty states.
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * <QueryTable<User>
35
+ * queryKey={['users']}
36
+ * queryFn={() => fetch('/api/users').then(r => r.json())}
37
+ * columns={[
38
+ * { key: 'name', header: 'Name', sortable: true },
39
+ * { key: 'email', header: 'Email' },
40
+ * ]}
41
+ * />
42
+ * ```
43
+ */
44
+ export declare function QueryTable<T>({ queryKey, queryFn, columns, pageSize, loadingFallback, errorFallback, emptyFallback, skeletonRows, }: QueryTableProps<T>): string | number | boolean | Iterable<ReactNode> | import("react/jsx-runtime").JSX.Element;
45
+ export {};
46
+ //# sourceMappingURL=QueryTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryTable.d.ts","sourceRoot":"","sources":["../src/QueryTable.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,uBAAuB,CAAC;AAEhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,KAAK,MAAM,CAAC,CAAC,IAAI;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI;IAC/B,gCAAgC;IAChC,QAAQ,EAAE,QAAQ,CAAC;IACnB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5B,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,0BAA0B;IAC1B,aAAa,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC;IAC1D,yDAAyD;IACzD,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,EAC5B,QAAQ,EACR,OAAO,EACP,OAAO,EACP,QAAQ,EACR,eAAe,EACf,aAAa,EACb,aAAa,EACb,YAAgB,GACjB,EAAE,eAAe,CAAC,CAAC,CAAC,6FAgDpB"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  import { type QueryKey } from '@tanstack/react-query';
2
2
  import type { ReactNode } from 'react';
3
+ export type { QueryBoundaryProps } from './QueryBoundary';
4
+ export { QueryBoundary } from './QueryBoundary';
5
+ export type { QueryListPage, QueryListProps } from './QueryList';
6
+ export { QueryList } from './QueryList';
7
+ export type { QueryTableProps } from './QueryTable';
8
+ export { QueryTable } from './QueryTable';
3
9
  type Column<T> = {
4
10
  key: string;
5
11
  header: string;
@@ -14,6 +20,6 @@ interface AsyncDataTableProps<T> {
14
20
  columns: Column<T>[];
15
21
  pageSize?: number;
16
22
  }
23
+ /** @deprecated Use `QueryTable` instead, which adds skeleton, error and empty states. */
17
24
  export declare function AsyncDataTable<T>({ queryKey, queryFn, columns, pageSize, }: AsyncDataTableProps<T>): import("react/jsx-runtime").JSX.Element;
18
- export {};
19
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,uBAAuB,CAAC;AAEhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,KAAK,MAAM,CAAC,CAAC,IAAI;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;CACjC,CAAC;AAEF,UAAU,mBAAmB,CAAC,CAAC;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAChC,QAAQ,EACR,OAAO,EACP,OAAO,EACP,QAAQ,GACT,EAAE,mBAAmB,CAAC,CAAC,CAAC,2CAOxB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,uBAAuB,CAAC;AAEhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM1C,KAAK,MAAM,CAAC,CAAC,IAAI;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;CACjC,CAAC;AAEF,UAAU,mBAAmB,CAAC,CAAC;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAChC,QAAQ,EACR,OAAO,EACP,OAAO,EACP,QAAQ,GACT,EAAE,mBAAmB,CAAC,CAAC,CAAC,2CAOxB"}
package/dist/index.esm.js CHANGED
@@ -1,7 +1,130 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import { useQuery } from '@tanstack/react-query';
3
- import { DataTable } from '@ui-construction-library/core';
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useQueryClient, useInfiniteQuery, useQuery } from '@tanstack/react-query';
3
+ import { Skeleton, EmptyState, DataTable } from '@ui-construction-library/core';
4
+ import { Suspense, Component } from 'react';
4
5
 
6
+ class QueryErrorBoundary extends Component {
7
+ constructor(props) {
8
+ super(props);
9
+ this.state = { error: null };
10
+ }
11
+ static getDerivedStateFromError(error) {
12
+ return { error };
13
+ }
14
+ componentDidCatch(error, info) {
15
+ console.error('[QueryBoundary]', error, info.componentStack);
16
+ }
17
+ handleReset = () => {
18
+ this.props.onReset?.();
19
+ this.setState({ error: null });
20
+ };
21
+ render() {
22
+ const { error } = this.state;
23
+ if (error) {
24
+ const { fallback } = this.props;
25
+ return typeof fallback === 'function'
26
+ ? fallback(error, this.handleReset)
27
+ : fallback;
28
+ }
29
+ return this.props.children;
30
+ }
31
+ }
32
+ /**
33
+ * Wraps query-consuming children with `Suspense` + an error boundary.
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * <QueryBoundary
38
+ * loadingFallback={<Skeleton />}
39
+ * errorFallback={(err, retry) => <div>Failed: {err.message} <button onClick={retry}>Retry</button></div>}
40
+ * queryKey={['users']}
41
+ * >
42
+ * <UsersList />
43
+ * </QueryBoundary>
44
+ * ```
45
+ */
46
+ function QueryBoundary({ loadingFallback = jsx("div", { "data-query-loading": "", children: "Loading\u2026" }), errorFallback, queryKey, children, }) {
47
+ const queryClient = useQueryClient();
48
+ const resolvedErrorFallback = errorFallback ??
49
+ ((err, retry) => (jsxs("div", { "data-query-error": "", role: "alert", children: [jsxs("p", { children: ["Something went wrong: ", err.message] }), jsx("button", { type: "button", onClick: retry, children: "Retry" })] })));
50
+ return (jsx(QueryErrorBoundary, { fallback: resolvedErrorFallback, onReset: () => {
51
+ if (queryKey) {
52
+ void queryClient.invalidateQueries({ queryKey });
53
+ }
54
+ }, children: jsx(Suspense, { fallback: loadingFallback, children: children }) }));
55
+ }
56
+
57
+ /**
58
+ * Infinite-scroll / load-more list backed by TanStack Query's `useInfiniteQuery`.
59
+ *
60
+ * @example
61
+ * ```tsx
62
+ * <QueryList<User>
63
+ * queryKey={['users-list']}
64
+ * queryFn={({ pageParam }) =>
65
+ * fetch(`/api/users?cursor=${pageParam ?? ''}`).then(r => r.json())
66
+ * }
67
+ * renderItem={(user) => <div>{user.name}</div>}
68
+ * />
69
+ * ```
70
+ */
71
+ function QueryList({ queryKey, queryFn, renderItem, loadingFallback, errorFallback, emptyFallback, loadMoreLabel = 'Load more', skeletonRows = 3, }) {
72
+ const { data, isLoading, isError, error, hasNextPage, isFetchingNextPage, fetchNextPage, } = useInfiniteQuery({
73
+ queryKey,
74
+ queryFn: ({ pageParam }) => queryFn({ pageParam: pageParam }),
75
+ initialPageParam: undefined,
76
+ getNextPageParam: (lastPage) => lastPage.nextCursor ?? undefined,
77
+ });
78
+ if (isLoading) {
79
+ return (loadingFallback ?? (jsx("div", { "data-query-list-loading": "", style: { display: 'grid', gap: '0.5rem' }, children: Array.from({ length: skeletonRows }).map((_, i) => (jsx(Skeleton, { style: { height: '2rem', width: '100%' } }, i))) })));
80
+ }
81
+ if (isError) {
82
+ const fallback = typeof errorFallback === 'function'
83
+ ? errorFallback(error)
84
+ : errorFallback;
85
+ return (fallback ?? (jsx("div", { "data-query-list-error": "", role: "alert", children: "Failed to load data." })));
86
+ }
87
+ const allItems = data?.pages.flatMap((page) => page.items) ?? [];
88
+ if (allItems.length === 0) {
89
+ return (emptyFallback ?? (jsx(EmptyState, { title: "No items", description: "There is nothing to display right now." })));
90
+ }
91
+ return (jsxs("div", { "data-query-list": "", children: [jsx("div", { "data-query-list-items": "", children: allItems.map((item, index) => renderItem(item, index)) }), hasNextPage && (jsx("button", { type: "button", onClick: () => void fetchNextPage(), disabled: isFetchingNextPage, "data-query-list-load-more": "", style: { marginTop: '1rem' }, children: isFetchingNextPage ? 'Loading…' : loadMoreLabel }))] }));
92
+ }
93
+
94
+ /**
95
+ * Data table pre-wired with TanStack Query loading, error and empty states.
96
+ *
97
+ * @example
98
+ * ```tsx
99
+ * <QueryTable<User>
100
+ * queryKey={['users']}
101
+ * queryFn={() => fetch('/api/users').then(r => r.json())}
102
+ * columns={[
103
+ * { key: 'name', header: 'Name', sortable: true },
104
+ * { key: 'email', header: 'Email' },
105
+ * ]}
106
+ * />
107
+ * ```
108
+ */
109
+ function QueryTable({ queryKey, queryFn, columns, pageSize, loadingFallback, errorFallback, emptyFallback, skeletonRows = 5, }) {
110
+ const { data, isLoading, isError, error } = useQuery({ queryKey, queryFn });
111
+ if (isLoading) {
112
+ return (loadingFallback ?? (jsx("div", { "data-query-table-loading": "", style: { display: 'grid', gap: '0.5rem' }, children: Array.from({ length: skeletonRows }).map((_, i) => (jsx(Skeleton, { style: { height: '2rem', width: '100%' } }, i))) })));
113
+ }
114
+ if (isError) {
115
+ const fallback = typeof errorFallback === 'function'
116
+ ? errorFallback(error)
117
+ : errorFallback;
118
+ return (fallback ?? (jsx("div", { "data-query-table-error": "", role: "alert", children: "Failed to load data." })));
119
+ }
120
+ const rows = data ?? [];
121
+ if (rows.length === 0) {
122
+ return (emptyFallback ?? (jsx(EmptyState, { title: "No records found", description: "There are no items to display right now." })));
123
+ }
124
+ return jsx(DataTable, { data: rows, columns: columns, pageSize: pageSize });
125
+ }
126
+
127
+ /** @deprecated Use `QueryTable` instead, which adds skeleton, error and empty states. */
5
128
  function AsyncDataTable({ queryKey, queryFn, columns, pageSize, }) {
6
129
  const { data = [], isLoading, isError } = useQuery({ queryKey, queryFn });
7
130
  if (isLoading)
@@ -11,5 +134,5 @@ function AsyncDataTable({ queryKey, queryFn, columns, pageSize, }) {
11
134
  return jsx(DataTable, { data: data, columns: columns, pageSize: pageSize });
12
135
  }
13
136
 
14
- export { AsyncDataTable };
137
+ export { AsyncDataTable, QueryBoundary, QueryList, QueryTable };
15
138
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/index.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":";;;;AAoBM,SAAU,cAAc,CAAI,EAChC,QAAQ,EACR,OAAO,EACP,OAAO,EACP,QAAQ,GACe,EAAA;AACvB,IAAA,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAEzE,IAAA,IAAI,SAAS;AAAE,QAAA,OAAOA,sCAAqB;AAC3C,IAAA,IAAI,OAAO;AAAE,QAAA,OAAOA,gDAA+B;AAEnD,IAAA,OAAOA,GAAA,CAAC,SAAS,EAAA,EAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAI;AACxE;;;;"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/QueryBoundary.tsx","../src/QueryList.tsx","../src/QueryTable.tsx","../src/index.tsx"],"sourcesContent":[null,null,null,null],"names":["_jsx","_jsxs"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -3,7 +3,130 @@
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var reactQuery = require('@tanstack/react-query');
5
5
  var core = require('@ui-construction-library/core');
6
+ var react = require('react');
6
7
 
8
+ class QueryErrorBoundary extends react.Component {
9
+ constructor(props) {
10
+ super(props);
11
+ this.state = { error: null };
12
+ }
13
+ static getDerivedStateFromError(error) {
14
+ return { error };
15
+ }
16
+ componentDidCatch(error, info) {
17
+ console.error('[QueryBoundary]', error, info.componentStack);
18
+ }
19
+ handleReset = () => {
20
+ this.props.onReset?.();
21
+ this.setState({ error: null });
22
+ };
23
+ render() {
24
+ const { error } = this.state;
25
+ if (error) {
26
+ const { fallback } = this.props;
27
+ return typeof fallback === 'function'
28
+ ? fallback(error, this.handleReset)
29
+ : fallback;
30
+ }
31
+ return this.props.children;
32
+ }
33
+ }
34
+ /**
35
+ * Wraps query-consuming children with `Suspense` + an error boundary.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * <QueryBoundary
40
+ * loadingFallback={<Skeleton />}
41
+ * errorFallback={(err, retry) => <div>Failed: {err.message} <button onClick={retry}>Retry</button></div>}
42
+ * queryKey={['users']}
43
+ * >
44
+ * <UsersList />
45
+ * </QueryBoundary>
46
+ * ```
47
+ */
48
+ function QueryBoundary({ loadingFallback = jsxRuntime.jsx("div", { "data-query-loading": "", children: "Loading\u2026" }), errorFallback, queryKey, children, }) {
49
+ const queryClient = reactQuery.useQueryClient();
50
+ const resolvedErrorFallback = errorFallback ??
51
+ ((err, retry) => (jsxRuntime.jsxs("div", { "data-query-error": "", role: "alert", children: [jsxRuntime.jsxs("p", { children: ["Something went wrong: ", err.message] }), jsxRuntime.jsx("button", { type: "button", onClick: retry, children: "Retry" })] })));
52
+ return (jsxRuntime.jsx(QueryErrorBoundary, { fallback: resolvedErrorFallback, onReset: () => {
53
+ if (queryKey) {
54
+ void queryClient.invalidateQueries({ queryKey });
55
+ }
56
+ }, children: jsxRuntime.jsx(react.Suspense, { fallback: loadingFallback, children: children }) }));
57
+ }
58
+
59
+ /**
60
+ * Infinite-scroll / load-more list backed by TanStack Query's `useInfiniteQuery`.
61
+ *
62
+ * @example
63
+ * ```tsx
64
+ * <QueryList<User>
65
+ * queryKey={['users-list']}
66
+ * queryFn={({ pageParam }) =>
67
+ * fetch(`/api/users?cursor=${pageParam ?? ''}`).then(r => r.json())
68
+ * }
69
+ * renderItem={(user) => <div>{user.name}</div>}
70
+ * />
71
+ * ```
72
+ */
73
+ function QueryList({ queryKey, queryFn, renderItem, loadingFallback, errorFallback, emptyFallback, loadMoreLabel = 'Load more', skeletonRows = 3, }) {
74
+ const { data, isLoading, isError, error, hasNextPage, isFetchingNextPage, fetchNextPage, } = reactQuery.useInfiniteQuery({
75
+ queryKey,
76
+ queryFn: ({ pageParam }) => queryFn({ pageParam: pageParam }),
77
+ initialPageParam: undefined,
78
+ getNextPageParam: (lastPage) => lastPage.nextCursor ?? undefined,
79
+ });
80
+ if (isLoading) {
81
+ return (loadingFallback ?? (jsxRuntime.jsx("div", { "data-query-list-loading": "", style: { display: 'grid', gap: '0.5rem' }, children: Array.from({ length: skeletonRows }).map((_, i) => (jsxRuntime.jsx(core.Skeleton, { style: { height: '2rem', width: '100%' } }, i))) })));
82
+ }
83
+ if (isError) {
84
+ const fallback = typeof errorFallback === 'function'
85
+ ? errorFallback(error)
86
+ : errorFallback;
87
+ return (fallback ?? (jsxRuntime.jsx("div", { "data-query-list-error": "", role: "alert", children: "Failed to load data." })));
88
+ }
89
+ const allItems = data?.pages.flatMap((page) => page.items) ?? [];
90
+ if (allItems.length === 0) {
91
+ return (emptyFallback ?? (jsxRuntime.jsx(core.EmptyState, { title: "No items", description: "There is nothing to display right now." })));
92
+ }
93
+ return (jsxRuntime.jsxs("div", { "data-query-list": "", children: [jsxRuntime.jsx("div", { "data-query-list-items": "", children: allItems.map((item, index) => renderItem(item, index)) }), hasNextPage && (jsxRuntime.jsx("button", { type: "button", onClick: () => void fetchNextPage(), disabled: isFetchingNextPage, "data-query-list-load-more": "", style: { marginTop: '1rem' }, children: isFetchingNextPage ? 'Loading…' : loadMoreLabel }))] }));
94
+ }
95
+
96
+ /**
97
+ * Data table pre-wired with TanStack Query loading, error and empty states.
98
+ *
99
+ * @example
100
+ * ```tsx
101
+ * <QueryTable<User>
102
+ * queryKey={['users']}
103
+ * queryFn={() => fetch('/api/users').then(r => r.json())}
104
+ * columns={[
105
+ * { key: 'name', header: 'Name', sortable: true },
106
+ * { key: 'email', header: 'Email' },
107
+ * ]}
108
+ * />
109
+ * ```
110
+ */
111
+ function QueryTable({ queryKey, queryFn, columns, pageSize, loadingFallback, errorFallback, emptyFallback, skeletonRows = 5, }) {
112
+ const { data, isLoading, isError, error } = reactQuery.useQuery({ queryKey, queryFn });
113
+ if (isLoading) {
114
+ return (loadingFallback ?? (jsxRuntime.jsx("div", { "data-query-table-loading": "", style: { display: 'grid', gap: '0.5rem' }, children: Array.from({ length: skeletonRows }).map((_, i) => (jsxRuntime.jsx(core.Skeleton, { style: { height: '2rem', width: '100%' } }, i))) })));
115
+ }
116
+ if (isError) {
117
+ const fallback = typeof errorFallback === 'function'
118
+ ? errorFallback(error)
119
+ : errorFallback;
120
+ return (fallback ?? (jsxRuntime.jsx("div", { "data-query-table-error": "", role: "alert", children: "Failed to load data." })));
121
+ }
122
+ const rows = data ?? [];
123
+ if (rows.length === 0) {
124
+ return (emptyFallback ?? (jsxRuntime.jsx(core.EmptyState, { title: "No records found", description: "There are no items to display right now." })));
125
+ }
126
+ return jsxRuntime.jsx(core.DataTable, { data: rows, columns: columns, pageSize: pageSize });
127
+ }
128
+
129
+ /** @deprecated Use `QueryTable` instead, which adds skeleton, error and empty states. */
7
130
  function AsyncDataTable({ queryKey, queryFn, columns, pageSize, }) {
8
131
  const { data = [], isLoading, isError } = reactQuery.useQuery({ queryKey, queryFn });
9
132
  if (isLoading)
@@ -14,4 +137,7 @@ function AsyncDataTable({ queryKey, queryFn, columns, pageSize, }) {
14
137
  }
15
138
 
16
139
  exports.AsyncDataTable = AsyncDataTable;
140
+ exports.QueryBoundary = QueryBoundary;
141
+ exports.QueryList = QueryList;
142
+ exports.QueryTable = QueryTable;
17
143
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.tsx"],"sourcesContent":[null],"names":["useQuery","_jsx","DataTable"],"mappings":";;;;;;AAoBM,SAAU,cAAc,CAAI,EAChC,QAAQ,EACR,OAAO,EACP,OAAO,EACP,QAAQ,GACe,EAAA;AACvB,IAAA,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,GAAGA,mBAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAEzE,IAAA,IAAI,SAAS;AAAE,QAAA,OAAOC,iDAAqB;AAC3C,IAAA,IAAI,OAAO;AAAE,QAAA,OAAOA,2DAA+B;AAEnD,IAAA,OAAOA,cAAA,CAACC,cAAS,EAAA,EAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAI;AACxE;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../src/QueryBoundary.tsx","../src/QueryList.tsx","../src/QueryTable.tsx","../src/index.tsx"],"sourcesContent":[null,null,null,null],"names":["Component","_jsx","useQueryClient","_jsxs","Suspense","useInfiniteQuery","Skeleton","EmptyState","useQuery","DataTable"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ui-construction-library/integration-tanstack-query",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org/"
@@ -8,19 +8,26 @@
8
8
  "main": "dist/index.js",
9
9
  "module": "dist/index.esm.js",
10
10
  "types": "dist/index.d.ts",
11
+ "scripts": {
12
+ "build": "rollup -c && tsc -p tsconfig.json --emitDeclarationOnly --declarationMap",
13
+ "test": "vitest run --config ./vitest.config.ts src",
14
+ "typecheck": "tsc --noEmit",
15
+ "lint": "biome check src"
16
+ },
11
17
  "peerDependencies": {
12
18
  "@tanstack/react-query": ">=5.0.0",
13
- "react": ">=18.0.0"
19
+ "react": ">=18.0.0",
20
+ "react-dom": ">=18.0.0"
14
21
  },
15
22
  "dependencies": {
16
- "@ui-construction-library/core": "^0.1.2"
23
+ "@ui-construction-library/core": "^0.2.0"
17
24
  },
18
25
  "devDependencies": {
19
- "@types/react": "^18.3.27",
26
+ "@types/react": "catalog:",
20
27
  "@rollup/plugin-typescript": "^12.1.2",
21
28
  "rollup": "^4.34.8",
22
29
  "typescript": "^6.0.3",
23
- "vitest": "^4.1.0"
30
+ "vitest": "catalog:"
24
31
  },
25
32
  "type": "module",
26
33
  "sideEffects": false,
@@ -31,10 +38,22 @@
31
38
  "types": "./dist/index.d.ts"
32
39
  }
33
40
  },
34
- "scripts": {
35
- "build": "rollup -c",
36
- "test": "vitest run --config ../../../vitest.config.ts src",
37
- "typecheck": "tsc --noEmit",
38
- "lint": "biome check src"
39
- }
40
- }
41
+ "description": "TanStack Query integration for @ui-construction-library — query-backed data components.",
42
+ "keywords": [
43
+ "tanstack-query",
44
+ "react-query",
45
+ "data-fetching",
46
+ "react",
47
+ "design-system"
48
+ ],
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/jilimb0/UI-Library.git",
52
+ "directory": "packages/integrations/tanstack-query"
53
+ },
54
+ "homepage": "https://github.com/jilimb0/UI-Library#readme",
55
+ "files": [
56
+ "dist",
57
+ "README.md"
58
+ ]
59
+ }
@@ -1,19 +0,0 @@
1
- import { type QueryKey } from '@tanstack/react-query';
2
- import type { ReactNode } from 'react';
3
- type Column<T> = {
4
- key: string;
5
- header: string;
6
- width?: number | string;
7
- sortable?: boolean;
8
- filterable?: boolean;
9
- render?: (item: T) => ReactNode;
10
- };
11
- interface AsyncDataTableProps<T> {
12
- queryKey: QueryKey;
13
- queryFn: () => Promise<T[]>;
14
- columns: Column<T>[];
15
- pageSize?: number;
16
- }
17
- export declare function AsyncDataTable<T>({ queryKey, queryFn, columns, pageSize, }: AsyncDataTableProps<T>): import("react/jsx-runtime").JSX.Element;
18
- export {};
19
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,uBAAuB,CAAC;AAEhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,KAAK,MAAM,CAAC,CAAC,IAAI;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;CACjC,CAAC;AAEF,UAAU,mBAAmB,CAAC,CAAC;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAChC,QAAQ,EACR,OAAO,EACP,OAAO,EACP,QAAQ,GACT,EAAE,mBAAmB,CAAC,CAAC,CAAC,2CAOxB"}
@@ -1,12 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useQuery } from '@tanstack/react-query';
3
- import { DataTable } from '@ui-construction-library/core';
4
- export function AsyncDataTable({ queryKey, queryFn, columns, pageSize, }) {
5
- const { data = [], isLoading, isError } = useQuery({ queryKey, queryFn });
6
- if (isLoading)
7
- return _jsx("div", { children: "Loading..." });
8
- if (isError)
9
- return _jsx("div", { children: "Failed to load data." });
10
- return _jsx(DataTable, { data: data, columns: columns, pageSize: pageSize });
11
- }
12
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAiB,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAmB1D,MAAM,UAAU,cAAc,CAAI,EAChC,QAAQ,EACR,OAAO,EACP,OAAO,EACP,QAAQ,GACe;IACvB,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAE1E,IAAI,SAAS;QAAE,OAAO,uCAAqB,CAAC;IAC5C,IAAI,OAAO;QAAE,OAAO,iDAA+B,CAAC;IAEpD,OAAO,KAAC,SAAS,IAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAI,CAAC;AACzE,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.tsx"],"names":[],"mappings":""}
@@ -1,37 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { render, screen } from '@testing-library/react';
3
- import { describe, expect, it, vi } from 'vitest';
4
- const useQueryMock = vi.fn();
5
- vi.mock('@tanstack/react-query', () => ({
6
- useQuery: (args) => useQueryMock(args),
7
- }));
8
- vi.mock('@ui-construction-library/core', () => ({
9
- DataTable: ({ data }) => (_jsxs("div", { children: ["rows:", data.length] })),
10
- }));
11
- import { AsyncDataTable } from './index';
12
- describe('integration-tanstack-query', () => {
13
- it('shows loading and error states and renders the data table on success', async () => {
14
- useQueryMock.mockReturnValueOnce({
15
- data: [],
16
- isLoading: true,
17
- isError: false,
18
- });
19
- const { rerender } = render(_jsx(AsyncDataTable, { queryKey: ['items'], queryFn: async () => [], columns: [] }));
20
- expect(screen.getByText('Loading...')).toBeTruthy();
21
- useQueryMock.mockReturnValueOnce({
22
- data: [],
23
- isLoading: false,
24
- isError: true,
25
- });
26
- rerender(_jsx(AsyncDataTable, { queryKey: ['items'], queryFn: async () => [], columns: [] }));
27
- expect(screen.getByText('Failed to load data.')).toBeTruthy();
28
- useQueryMock.mockReturnValueOnce({
29
- data: [{ name: 'A' }],
30
- isLoading: false,
31
- isError: false,
32
- });
33
- rerender(_jsx(AsyncDataTable, { queryKey: ['items'], queryFn: async () => [], columns: [] }));
34
- expect(screen.getByText('rows:1')).toBeTruthy();
35
- });
36
- });
37
- //# sourceMappingURL=index.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAElD,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AAE7B,EAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC,QAAQ,EAAE,CAAC,IAAa,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;CAChD,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,+BAA+B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9C,SAAS,EAAE,CAAC,EAAE,IAAI,EAAqC,EAAE,EAAE,CAAC,CAC1D,mCAAW,IAAI,CAAC,MAAM,IAAO,CAC9B;CACF,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;QACpF,YAAY,CAAC,mBAAmB,CAAC;YAC/B,IAAI,EAAE,EAAE;YACR,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CACzB,KAAC,cAAc,IACb,QAAQ,EAAE,CAAC,OAAO,CAAC,EACnB,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE,EACvB,OAAO,EAAE,EAAE,GACX,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;QAEpD,YAAY,CAAC,mBAAmB,CAAC;YAC/B,IAAI,EAAE,EAAE;YACR,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QACH,QAAQ,CACN,KAAC,cAAc,IACb,QAAQ,EAAE,CAAC,OAAO,CAAC,EACnB,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE,EACvB,OAAO,EAAE,EAAE,GACX,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;QAE9D,YAAY,CAAC,mBAAmB,CAAC;YAC/B,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;YACrB,SAAS,EAAE,KAAK;YAChB,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QACH,QAAQ,CACN,KAAC,cAAc,IACb,QAAQ,EAAE,CAAC,OAAO,CAAC,EACnB,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE,EACvB,OAAO,EAAE,EAAE,GACX,CACH,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}