@jobber/hooks 2.0.3-pre1.55 → 2.0.3-pre2.52

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 (71) hide show
  1. package/dist/index.d.ts +10 -7
  2. package/dist/index.js +10 -8
  3. package/dist/useAssert/index.d.ts +1 -1
  4. package/dist/useAssert/index.js +2 -2
  5. package/dist/useCollectionQuery/index.d.ts +1 -0
  6. package/dist/useCollectionQuery/index.js +5 -0
  7. package/dist/useCollectionQuery/mdxUtils.d.ts +53 -0
  8. package/dist/useCollectionQuery/mdxUtils.js +152 -0
  9. package/dist/useCollectionQuery/test-utilities/index.d.ts +3 -0
  10. package/dist/useCollectionQuery/test-utilities/index.js +19 -0
  11. package/dist/useCollectionQuery/test-utilities/mocks.d.ts +107 -0
  12. package/dist/useCollectionQuery/test-utilities/mocks.js +131 -0
  13. package/dist/useCollectionQuery/test-utilities/queries.d.ts +37 -0
  14. package/dist/useCollectionQuery/test-utilities/queries.js +59 -0
  15. package/dist/useCollectionQuery/test-utilities/utils.d.ts +1 -0
  16. package/dist/useCollectionQuery/test-utilities/utils.js +18 -0
  17. package/dist/useCollectionQuery/uniqueEdges.d.ts +8 -0
  18. package/dist/useCollectionQuery/uniqueEdges.js +19 -0
  19. package/dist/useCollectionQuery/uniqueNodes.d.ts +5 -0
  20. package/dist/useCollectionQuery/uniqueNodes.js +11 -0
  21. package/dist/useCollectionQuery/useCollectionQuery.d.ts +71 -0
  22. package/dist/useCollectionQuery/useCollectionQuery.js +181 -0
  23. package/dist/useCollectionQuery/useCollectionQuery.test.d.ts +1 -0
  24. package/dist/useCollectionQuery/useCollectionQuery.test.js +327 -0
  25. package/dist/useFocusTrap/index.d.ts +1 -1
  26. package/dist/useFocusTrap/index.js +2 -2
  27. package/dist/useFocusTrap/useFocusTrap.test.d.ts +1 -0
  28. package/dist/useFocusTrap/useFocusTrap.test.js +52 -0
  29. package/dist/useFormState/index.d.ts +1 -1
  30. package/dist/useFormState/index.js +2 -2
  31. package/dist/useIsMounted/index.d.ts +1 -1
  32. package/dist/useIsMounted/index.js +2 -2
  33. package/dist/useIsMounted/useIsMounted.test.js +3 -3
  34. package/dist/useLiveAnnounce/index.d.ts +1 -1
  35. package/dist/useLiveAnnounce/index.js +2 -2
  36. package/dist/useLiveAnnounce/useLiveAnnounce.test.js +2 -2
  37. package/dist/useOnKeyDown/index.d.ts +1 -0
  38. package/dist/useOnKeyDown/index.js +5 -0
  39. package/dist/useOnKeyDown/useOnKeyDown.d.ts +13 -0
  40. package/dist/useOnKeyDown/useOnKeyDown.js +33 -0
  41. package/dist/useOnKeyDown/useOnKeyDown.test.d.ts +1 -0
  42. package/dist/useOnKeyDown/useOnKeyDown.test.js +23 -0
  43. package/dist/usePasswordStrength/index.d.ts +1 -1
  44. package/dist/usePasswordStrength/index.js +2 -2
  45. package/dist/useRefocusOnActivator/index.d.ts +1 -1
  46. package/dist/useRefocusOnActivator/index.js +2 -2
  47. package/dist/useResizeObserver/index.d.ts +1 -0
  48. package/dist/useResizeObserver/index.js +17 -0
  49. package/dist/useResizeObserver/useResizeObserver.d.ts +19 -0
  50. package/dist/useResizeObserver/useResizeObserver.js +58 -0
  51. package/package.json +9 -9
  52. package/useAssert.d.ts +1 -0
  53. package/useAssert.js +17 -0
  54. package/useCollectionQuery.d.ts +1 -0
  55. package/useCollectionQuery.js +17 -0
  56. package/useFocusTrap.d.ts +1 -0
  57. package/useFocusTrap.js +17 -0
  58. package/useFormState.d.ts +1 -0
  59. package/useFormState.js +17 -0
  60. package/useIsMounted.d.ts +1 -0
  61. package/useIsMounted.js +17 -0
  62. package/useLiveAnnounce.d.ts +1 -0
  63. package/useLiveAnnounce.js +17 -0
  64. package/useOnKeyDown.d.ts +1 -0
  65. package/useOnKeyDown.js +17 -0
  66. package/usePasswordStrength.d.ts +1 -0
  67. package/usePasswordStrength.js +17 -0
  68. package/useRefocusOnActivator.d.ts +1 -0
  69. package/useRefocusOnActivator.js +17 -0
  70. package/useResizeObserver.d.ts +1 -0
  71. package/useResizeObserver.js +17 -0
@@ -0,0 +1,5 @@
1
+ export interface Node {
2
+ id: unknown;
3
+ __typename?: unknown;
4
+ }
5
+ export declare function uniqueNodes(nodes: Node[]): Node[];
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.uniqueNodes = void 0;
4
+ function uniqueNodes(nodes) {
5
+ const result = new Map();
6
+ nodes.forEach(node => {
7
+ result.set(`${node.__typename}-${node.id}`, node);
8
+ });
9
+ return Array.from(result.values());
10
+ }
11
+ exports.uniqueNodes = uniqueNodes;
@@ -0,0 +1,71 @@
1
+ import { ApolloError, DocumentNode, QueryHookOptions, SubscribeToMoreOptions } from "@apollo/client";
2
+ import { Node } from "./uniqueNodes";
3
+ import { Edge } from "./uniqueEdges";
4
+ interface UseCollectionQueryArguments<TQuery, TSubscription> {
5
+ /**
6
+ * The graphQL query that fetches the collection
7
+ */
8
+ query: DocumentNode;
9
+ /**
10
+ * A list of options for us to pass into the apollo `useQuery` hook
11
+ */
12
+ queryOptions?: QueryHookOptions<TQuery>;
13
+ /**
14
+ * A function that returns the location where the {@link Collection} is located.
15
+ *
16
+ * The collection is the part of the result that needs to be paginated.
17
+ */
18
+ getCollectionByPath: GetCollectionByPathFunction<TQuery>;
19
+ /**
20
+ * A list of subscription options if you want to create a GraphQL
21
+ * subscription to listen for more content.
22
+ */
23
+ subscription?: ListSubscription<TSubscription>;
24
+ }
25
+ interface ListSubscription<TSubscription> {
26
+ /**
27
+ * The graphQL subscription that listens for more data. This query should
28
+ * return a single Node that matches the data structure in
29
+ * `getCollectionByPath<TQuery>(...).edges.node` and
30
+ * `getCollectionByPath<TQuery>(...).nodes
31
+ */
32
+ document: DocumentNode;
33
+ /**
34
+ * A list of variables to pass into the apollo `subscribeToMore` function.
35
+ */
36
+ options?: Pick<SubscribeToMoreOptions<TSubscription>, "variables">;
37
+ /**
38
+ * A function that returns the location where the `Node` is located on the
39
+ * `TSubscription` object.
40
+ *
41
+ * It should return a single Node that matches the data structure in
42
+ * `getCollectionByPath<TQuery>(...).edges.node` and
43
+ * `getCollectionByPath<TQuery>(...).nodes
44
+ */
45
+ getNodeByPath: GetNodeByPath<TSubscription>;
46
+ }
47
+ interface Collection {
48
+ edges?: Edge[];
49
+ nodes?: Node[];
50
+ pageInfo: {
51
+ endCursor?: string | undefined;
52
+ hasNextPage: boolean;
53
+ [otherProperties: string]: unknown;
54
+ };
55
+ totalCount?: number;
56
+ [otherProperties: string]: unknown;
57
+ }
58
+ interface CollectionQueryResult<TQuery> {
59
+ data: TQuery | undefined;
60
+ error: ApolloError | undefined;
61
+ loadingRefresh: boolean;
62
+ loadingNextPage: boolean;
63
+ loadingInitialContent: boolean;
64
+ refresh(): void;
65
+ nextPage(): void;
66
+ }
67
+ type GetCollectionByPathFunction<TQuery> = (data: TQuery | undefined) => Collection | undefined;
68
+ type GetNodeByPath<TSubscription> = (data: TSubscription | undefined) => Node | undefined;
69
+ export declare function useCollectionQuery<TQuery, TSubscription = undefined>({ query, queryOptions, getCollectionByPath, subscription, }: UseCollectionQueryArguments<TQuery, TSubscription>): CollectionQueryResult<TQuery>;
70
+ export declare function isAlreadyUpdated(outputCollection: Collection, newNode: Node): boolean;
71
+ export {};
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isAlreadyUpdated = exports.useCollectionQuery = void 0;
4
+ const client_1 = require("@apollo/client");
5
+ const lodash_1 = require("lodash");
6
+ const react_1 = require("react");
7
+ const formatters_1 = require("@jobber/formatters");
8
+ const uniqueNodes_1 = require("./uniqueNodes");
9
+ const uniqueEdges_1 = require("./uniqueEdges");
10
+ const useIsMounted_1 = require("../useIsMounted");
11
+ function useCollectionQuery({ query, queryOptions, getCollectionByPath, subscription, }) {
12
+ var _a, _b;
13
+ const { data, loading, refetch, error, fetchMore, subscribeToMore } = (0, client_1.useQuery)(query, queryOptions);
14
+ const isMounted = (0, useIsMounted_1.useIsMounted)();
15
+ const [loadingRefresh, setLoadingRefresh] = (0, react_1.useState)(false);
16
+ const [loadingNextPage, setLoadingNextPage] = (0, react_1.useState)(false);
17
+ const loadingInitialContent = loading && !loadingRefresh && !loadingNextPage;
18
+ const isSearching = !!((_a = queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.variables) === null || _a === void 0 ? void 0 : _a.searchTerm);
19
+ const refresh = (0, react_1.useCallback)(() => {
20
+ if (loadingInitialContent || loadingRefresh) {
21
+ return;
22
+ }
23
+ setLoadingRefresh(true);
24
+ fetchMore({
25
+ // a workaround fix for the error described in this post
26
+ // https://github.com/apollographql/apollo-client/issues/7491#issuecomment-767985363
27
+ // These changes can be reverted once we can update to version 3.4
28
+ // (the current release candidate)
29
+ variables: {},
30
+ updateQuery: (prev, { fetchMoreResult }) => fetchMoreResult || prev,
31
+ })
32
+ .catch(err => formatters_1.config.errorNotifier("Refetch Error", err))
33
+ .finally(() => {
34
+ if (isMounted.current) {
35
+ setLoadingRefresh(false);
36
+ }
37
+ });
38
+ }, [
39
+ loadingInitialContent,
40
+ loadingRefresh,
41
+ setLoadingRefresh,
42
+ refetch,
43
+ isMounted,
44
+ ]);
45
+ const nextPage = (0, react_1.useCallback)(() => {
46
+ var _a;
47
+ if (loadingInitialContent || loadingRefresh || loadingNextPage) {
48
+ return;
49
+ }
50
+ const pageInfo = (_a = getCollectionByPath(data)) === null || _a === void 0 ? void 0 : _a.pageInfo;
51
+ if (!pageInfo || !pageInfo.hasNextPage) {
52
+ return;
53
+ }
54
+ setLoadingNextPage(true);
55
+ fetchMore({
56
+ variables: {
57
+ cursor: pageInfo.endCursor,
58
+ },
59
+ updateQuery: (prev, { fetchMoreResult }) => fetchMoreUpdateQueryHandler(prev, fetchMoreResult, getCollectionByPath),
60
+ })
61
+ .catch(err => formatters_1.config.errorNotifier("FetchMore Error", err))
62
+ .finally(() => {
63
+ if (isMounted.current) {
64
+ setLoadingNextPage(false);
65
+ }
66
+ });
67
+ }, [
68
+ data,
69
+ loadingInitialContent,
70
+ loadingRefresh,
71
+ fetchMore,
72
+ loadingNextPage,
73
+ setLoadingNextPage,
74
+ getCollectionByPath,
75
+ isMounted,
76
+ ]);
77
+ (0, react_1.useEffect)(() => {
78
+ if (subscription == undefined)
79
+ return;
80
+ const subscriptionOptions = subscription.options || {};
81
+ return subscribeToMore(Object.assign(Object.assign({}, subscriptionOptions), { document: subscription.document, updateQuery: (prev, { subscriptionData }) => subscribeToMoreHandler(isSearching, prev, getCollectionByPath, subscriptionData === null || subscriptionData === void 0 ? void 0 : subscriptionData.data, subscription.getNodeByPath), onError: err => formatters_1.config.errorNotifier("Subscribe to More Error", err) }));
82
+ },
83
+ // Disabling this linter so we can force this only run once. If we didn't
84
+ // do this we would need to ensure subscription, subscribeToMore, and getNodeByPath
85
+ // all use useCallback.
86
+ [(_b = queryOptions === null || queryOptions === void 0 ? void 0 : queryOptions.variables) === null || _b === void 0 ? void 0 : _b.searchTerm]);
87
+ return {
88
+ data,
89
+ error,
90
+ refresh,
91
+ loadingRefresh,
92
+ nextPage,
93
+ loadingNextPage,
94
+ loadingInitialContent,
95
+ };
96
+ }
97
+ exports.useCollectionQuery = useCollectionQuery;
98
+ /**
99
+ * The following method uses an `output` variable, and indirectly modifies it through the `outputCollection` variable.
100
+ * This type of indirect modification is prone to bugs, but I couldn't think of a better way to write this code.
101
+ *
102
+ * Here's what I was balancing:
103
+ * 1. We need to copy the structure of prev to ensure that when we're combining two objects, we're not losing properties
104
+ * 2. We need to extract a key from an unknown path that's given to us by getCollectionByPath and then we need to modify
105
+ * that, and ensure that it's properly set on the cloned output object.
106
+ * 3. We want to keep the interface to this hook as simple and easy to use as possible
107
+ *
108
+ * The alternative approaches that were rejected:
109
+ * 1. We replace the getCollectionByPath with a keyPath string. (Eg. "data.conversation.message") and then we use lodash
110
+ * `get` and `set` which should remove all the object manipulation. But, this approach loses us the type safety that
111
+ * getCollectionByPath gives us
112
+ * 2. We could add a setCollection function to the list of arguments for this hook. This leaves us with type safety but
113
+ * makes the `useCollectionQuery` interface more complicated by adding arguments
114
+ */
115
+ function fetchMoreUpdateQueryHandler(prev, fetchMoreResult, getCollectionByPath) {
116
+ const nextCollection = getCollectionByPath(fetchMoreResult);
117
+ const output = (0, lodash_1.cloneDeep)(prev);
118
+ const outputCollection = getCollectionByPath(output);
119
+ if (outputCollection === undefined || nextCollection === undefined) {
120
+ return output;
121
+ }
122
+ if (outputCollection.nodes && nextCollection.nodes) {
123
+ outputCollection.nodes = getUpdatedNodes(outputCollection.nodes, nextCollection.nodes);
124
+ }
125
+ if (outputCollection.edges && nextCollection.edges) {
126
+ outputCollection.edges = getUpdatedEdges(outputCollection.edges, nextCollection.edges);
127
+ }
128
+ Object.assign(outputCollection, Object.assign({ pageInfo: (0, lodash_1.cloneDeep)(nextCollection.pageInfo) }, getTotalCount(nextCollection.totalCount)));
129
+ return output;
130
+ }
131
+ function subscribeToMoreHandler(isSearching, prev, getCollectionByPath, subscriptionData, getNodeByPath) {
132
+ const node = getNodeByPath(subscriptionData);
133
+ const output = (0, lodash_1.cloneDeep)(prev);
134
+ const outputCollection = getCollectionByPath(output);
135
+ if (outputCollection == undefined || node == undefined)
136
+ return output;
137
+ if (isAlreadyUpdated(outputCollection, node) || isSearching) {
138
+ return prev;
139
+ }
140
+ if (outputCollection.nodes) {
141
+ outputCollection.nodes = getUpdatedNodes(outputCollection.nodes, [node], false);
142
+ }
143
+ if (outputCollection.edges) {
144
+ outputCollection.edges = getUpdatedEdges(outputCollection.edges, [(0, uniqueEdges_1.createEdge)(node)], false);
145
+ }
146
+ Object.assign(outputCollection, Object.assign({ pageInfo: (0, lodash_1.cloneDeep)(outputCollection.pageInfo) }, getTotalCount(outputCollection.totalCount, 1)));
147
+ return output;
148
+ }
149
+ function getTotalCount(totalCount, additionalCount = 0) {
150
+ return totalCount !== undefined
151
+ ? { totalCount: totalCount + additionalCount }
152
+ : {};
153
+ }
154
+ function isAlreadyUpdated(outputCollection, newNode) {
155
+ let edgesAlreadyUpdated = true;
156
+ let nodesAlreadyUpdated = true;
157
+ if (outputCollection.edges) {
158
+ edgesAlreadyUpdated = outputCollection.edges.some(edge => {
159
+ return edge.node.id === newNode.id;
160
+ });
161
+ }
162
+ if (outputCollection.nodes) {
163
+ nodesAlreadyUpdated = outputCollection.nodes.some(node => {
164
+ return node.id === newNode.id;
165
+ });
166
+ }
167
+ return edgesAlreadyUpdated && nodesAlreadyUpdated;
168
+ }
169
+ exports.isAlreadyUpdated = isAlreadyUpdated;
170
+ function getUpdatedEdges(prevEdges, nextEdges, appendToEnd = true) {
171
+ const newEdges = appendToEnd
172
+ ? [...prevEdges, ...nextEdges]
173
+ : [...nextEdges, ...prevEdges];
174
+ return (0, uniqueEdges_1.uniqueEdges)(newEdges);
175
+ }
176
+ function getUpdatedNodes(prevNodes, nextNodes, appendToEnd = true) {
177
+ const newNodes = appendToEnd
178
+ ? [...prevNodes, ...nextNodes]
179
+ : [...nextNodes, ...prevNodes];
180
+ return (0, uniqueNodes_1.uniqueNodes)(newNodes);
181
+ }
@@ -0,0 +1,327 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const react_hooks_1 = require("@testing-library/react-hooks");
13
+ const react_1 = require("@testing-library/react");
14
+ const useCollectionQuery_1 = require("./useCollectionQuery");
15
+ const test_utilities_1 = require("./test-utilities");
16
+ beforeEach(() => {
17
+ (0, test_utilities_1.setListQueryMockHasNextPage)(true);
18
+ test_utilities_1.listQueryResponseMock.mockClear();
19
+ test_utilities_1.subscriptionQueryMock.mockClear();
20
+ });
21
+ function useCollectionQueryHook(query) {
22
+ return (0, useCollectionQuery_1.useCollectionQuery)({
23
+ query: query,
24
+ getCollectionByPath(data) {
25
+ var _a;
26
+ return (_a = data === null || data === void 0 ? void 0 : data.conversation) === null || _a === void 0 ? void 0 : _a.smsMessages;
27
+ },
28
+ });
29
+ }
30
+ function useCollectionQueryHookWithSubscription(query) {
31
+ return (0, useCollectionQuery_1.useCollectionQuery)({
32
+ query: query,
33
+ getCollectionByPath(data) {
34
+ var _a;
35
+ return (_a = data === null || data === void 0 ? void 0 : data.conversation) === null || _a === void 0 ? void 0 : _a.smsMessages;
36
+ },
37
+ subscription: {
38
+ document: test_utilities_1.SUBSCRIPTION_QUERY,
39
+ getNodeByPath(conversationData) {
40
+ var _a;
41
+ return (_a = conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationMessage) === null || _a === void 0 ? void 0 : _a.smsMessage;
42
+ },
43
+ },
44
+ });
45
+ }
46
+ function useCollectionQueryHookWithSubscriptionAndSearch(query, searchTerm) {
47
+ return (0, useCollectionQuery_1.useCollectionQuery)({
48
+ query: query,
49
+ queryOptions: {
50
+ variables: {
51
+ searchTerm: searchTerm,
52
+ },
53
+ },
54
+ getCollectionByPath(data) {
55
+ var _a;
56
+ return (_a = data === null || data === void 0 ? void 0 : data.conversation) === null || _a === void 0 ? void 0 : _a.smsMessages;
57
+ },
58
+ subscription: {
59
+ document: test_utilities_1.SUBSCRIPTION_QUERY,
60
+ getNodeByPath(conversationData) {
61
+ var _a;
62
+ return (_a = conversationData === null || conversationData === void 0 ? void 0 : conversationData.conversationMessage) === null || _a === void 0 ? void 0 : _a.smsMessage;
63
+ },
64
+ },
65
+ });
66
+ }
67
+ describe("useCollectionQuery", () => {
68
+ describe.each `
69
+ testCase | query | responseMock
70
+ ${"excludes totalCount"} | ${test_utilities_1.LIST_QUERY} | ${test_utilities_1.listQueryResponseMock}
71
+ ${"includes totalCount"} | ${test_utilities_1.LIST_QUERY_WITH_TOTAL_COUNT} | ${test_utilities_1.listQueryWithTotalCountResponseMock}
72
+ `("when the query run $testCase", ({ query, responseMock }) => {
73
+ describe("when useCollectionQuery is first called", () => {
74
+ describe("when nextPage is called while it's still loading initial content", () => {
75
+ it("should not trigger a the next page to be fetched", () => __awaiter(void 0, void 0, void 0, function* () {
76
+ const { result } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHook(query), {
77
+ wrapper: (0, test_utilities_1.wrapper)([
78
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
79
+ (0, test_utilities_1.buildListRequestMockForNextPage)(query, responseMock),
80
+ ]),
81
+ });
82
+ (0, react_hooks_1.act)(() => {
83
+ result.current.nextPage();
84
+ });
85
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
86
+ expect(responseMock).toHaveBeenCalledTimes(1);
87
+ }));
88
+ });
89
+ describe("when refresh is called while it's still loading initial content", () => {
90
+ it("should not trigger a refresh", () => __awaiter(void 0, void 0, void 0, function* () {
91
+ const { result } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHook(query), {
92
+ wrapper: (0, test_utilities_1.wrapper)([
93
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
94
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
95
+ ]),
96
+ });
97
+ (0, react_hooks_1.act)(() => {
98
+ result.current.refresh();
99
+ });
100
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
101
+ expect(responseMock).toHaveBeenCalledTimes(1);
102
+ }));
103
+ });
104
+ describe("when there is no error", () => {
105
+ it("should update data", () => __awaiter(void 0, void 0, void 0, function* () {
106
+ var _a, _b, _c, _d;
107
+ const { result } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHook(query), {
108
+ wrapper: (0, test_utilities_1.wrapper)([(0, test_utilities_1.buildListRequestMock)(query, responseMock)]),
109
+ });
110
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
111
+ expect((_d = (_c = (_b = (_a = result.current.data) === null || _a === void 0 ? void 0 : _a.conversation) === null || _b === void 0 ? void 0 : _b.smsMessages) === null || _c === void 0 ? void 0 : _c.edges) === null || _d === void 0 ? void 0 : _d.length).toBe(1);
112
+ }));
113
+ it("should set initialLoading while loading data", () => __awaiter(void 0, void 0, void 0, function* () {
114
+ const { result } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHook(query), {
115
+ wrapper: (0, test_utilities_1.wrapper)([(0, test_utilities_1.buildListRequestMock)(query, responseMock)]),
116
+ });
117
+ expect(result.current.loadingInitialContent).toBe(true);
118
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
119
+ }));
120
+ });
121
+ });
122
+ describe("#nextPage", () => {
123
+ describe("when nextPage is called while it's still loadingNextPage", () => {
124
+ it("should not trigger a nextPage", () => __awaiter(void 0, void 0, void 0, function* () {
125
+ const { result } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHook(query), {
126
+ wrapper: (0, test_utilities_1.wrapper)([
127
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
128
+ (0, test_utilities_1.buildListRequestMockForNextPage)(query, responseMock),
129
+ (0, test_utilities_1.buildListRequestMockForNextPage)(query, responseMock),
130
+ ]),
131
+ });
132
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
133
+ (0, react_hooks_1.act)(() => {
134
+ result.current.nextPage();
135
+ });
136
+ (0, react_hooks_1.act)(() => {
137
+ result.current.nextPage();
138
+ });
139
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
140
+ yield (0, react_1.waitFor)(() => {
141
+ var _a, _b, _c;
142
+ expect((_c = (_b = (_a = result.current.data) === null || _a === void 0 ? void 0 : _a.conversation) === null || _b === void 0 ? void 0 : _b.smsMessages) === null || _c === void 0 ? void 0 : _c.edges).toHaveLength(2);
143
+ });
144
+ }));
145
+ });
146
+ describe("when refresh is called while it's still loadingNextPage", () => {
147
+ it("should trigger a refresh", () => __awaiter(void 0, void 0, void 0, function* () {
148
+ const { result } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHook(query), {
149
+ wrapper: (0, test_utilities_1.wrapper)([
150
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
151
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
152
+ (0, test_utilities_1.buildListRequestMockForNextPage)(query, responseMock),
153
+ ]),
154
+ });
155
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
156
+ (0, react_hooks_1.act)(() => {
157
+ result.current.nextPage();
158
+ });
159
+ (0, react_hooks_1.act)(() => {
160
+ result.current.refresh();
161
+ });
162
+ expect(result.current.loadingRefresh).toBe(true);
163
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
164
+ }));
165
+ });
166
+ describe("when there is no more data to fetch", () => {
167
+ it("should not fetch more data", () => __awaiter(void 0, void 0, void 0, function* () {
168
+ (0, test_utilities_1.setListQueryMockHasNextPage)(false);
169
+ const { result } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHook(query), {
170
+ wrapper: (0, test_utilities_1.wrapper)([
171
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
172
+ (0, test_utilities_1.buildListRequestMockForNextPage)(query, responseMock),
173
+ ]),
174
+ });
175
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
176
+ (0, react_hooks_1.act)(() => {
177
+ result.current.nextPage();
178
+ });
179
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
180
+ expect(responseMock).toHaveBeenCalledTimes(1);
181
+ }));
182
+ });
183
+ describe("when there is no error", () => {
184
+ it("should update data", () => __awaiter(void 0, void 0, void 0, function* () {
185
+ const { result } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHook(query), {
186
+ wrapper: (0, test_utilities_1.wrapper)([
187
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
188
+ (0, test_utilities_1.buildListRequestMockForNextPage)(query, responseMock),
189
+ ]),
190
+ });
191
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
192
+ (0, react_hooks_1.act)(() => {
193
+ result.current.nextPage();
194
+ });
195
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
196
+ yield (0, react_1.waitFor)(() => {
197
+ var _a, _b, _c;
198
+ expect((_c = (_b = (_a = result.current.data) === null || _a === void 0 ? void 0 : _a.conversation) === null || _b === void 0 ? void 0 : _b.smsMessages) === null || _c === void 0 ? void 0 : _c.edges).toHaveLength(2);
199
+ });
200
+ }));
201
+ it("should set loadingNextPage while loading data", () => __awaiter(void 0, void 0, void 0, function* () {
202
+ const { result } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHook(query), {
203
+ wrapper: (0, test_utilities_1.wrapper)([
204
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
205
+ (0, test_utilities_1.buildListRequestMockForNextPage)(query, responseMock),
206
+ ]),
207
+ });
208
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
209
+ (0, react_hooks_1.act)(() => {
210
+ result.current.nextPage();
211
+ });
212
+ expect(result.current.loadingNextPage).toBe(true);
213
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
214
+ }));
215
+ });
216
+ });
217
+ describe("#refresh", () => {
218
+ describe("when refresh is called while it's still loadingRefresh", () => {
219
+ it("should not trigger a refresh", () => __awaiter(void 0, void 0, void 0, function* () {
220
+ const { result } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHook(query), {
221
+ wrapper: (0, test_utilities_1.wrapper)([
222
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
223
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
224
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
225
+ ]),
226
+ });
227
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
228
+ (0, react_hooks_1.act)(() => {
229
+ result.current.refresh();
230
+ });
231
+ (0, react_hooks_1.act)(() => {
232
+ result.current.refresh();
233
+ });
234
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
235
+ expect(responseMock).toHaveBeenCalledTimes(2);
236
+ }));
237
+ });
238
+ describe("when nextPage is called while it's still loadingRefresh", () => {
239
+ it("should not trigger a nextPage", () => __awaiter(void 0, void 0, void 0, function* () {
240
+ const { result } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHook(query), {
241
+ wrapper: (0, test_utilities_1.wrapper)([
242
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
243
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
244
+ (0, test_utilities_1.buildListRequestMockForNextPage)(query, responseMock),
245
+ ]),
246
+ });
247
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
248
+ (0, react_hooks_1.act)(() => {
249
+ result.current.refresh();
250
+ });
251
+ (0, react_hooks_1.act)(() => {
252
+ result.current.nextPage();
253
+ });
254
+ expect(result.current.loadingNextPage).toBe(false);
255
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
256
+ }));
257
+ });
258
+ describe("when there is no error", () => {
259
+ it("should set loadingRefresh while loading data", () => __awaiter(void 0, void 0, void 0, function* () {
260
+ const { result } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHook(query), {
261
+ wrapper: (0, test_utilities_1.wrapper)([
262
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
263
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock),
264
+ ]),
265
+ });
266
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
267
+ (0, react_hooks_1.act)(() => {
268
+ result.current.refresh();
269
+ });
270
+ expect(result.current.loadingRefresh).toBe(true);
271
+ yield (0, react_hooks_1.act)(test_utilities_1.wait);
272
+ }));
273
+ });
274
+ });
275
+ describe("#subscribeToMore", () => {
276
+ describe("when hook receives update from item not in collection", () => {
277
+ it("should add new item to collection", () => __awaiter(void 0, void 0, void 0, function* () {
278
+ var _a, _b, _c, _d, _e;
279
+ const { result, waitForNextUpdate } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHookWithSubscription(query), {
280
+ wrapper: (0, test_utilities_1.wrapper)([
281
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock, "1"),
282
+ (0, test_utilities_1.buildSubscriptionRequestMock)("2"),
283
+ ]),
284
+ });
285
+ // Wait for initial load
286
+ yield (0, react_hooks_1.act)(waitForNextUpdate);
287
+ // Wait for subscription
288
+ yield (0, react_hooks_1.act)(waitForNextUpdate);
289
+ expect((_e = (_d = (_c = (_b = (_a = result === null || result === void 0 ? void 0 : result.current) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.conversation) === null || _c === void 0 ? void 0 : _c.smsMessages) === null || _d === void 0 ? void 0 : _d.edges) === null || _e === void 0 ? void 0 : _e.length).toBe(2);
290
+ }));
291
+ });
292
+ describe("when hook receives update from item already in collection", () => {
293
+ it("should return the existing collection", () => __awaiter(void 0, void 0, void 0, function* () {
294
+ var _a, _b, _c, _d, _e;
295
+ const { result, waitForNextUpdate } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHookWithSubscription(query), {
296
+ wrapper: (0, test_utilities_1.wrapper)([
297
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock, "1"),
298
+ (0, test_utilities_1.buildSubscriptionRequestMock)("1"),
299
+ ]),
300
+ });
301
+ // Wait for initial load
302
+ yield (0, react_hooks_1.act)(waitForNextUpdate);
303
+ // Wait for subscription
304
+ yield (0, react_hooks_1.act)(() => (0, test_utilities_1.wait)(200));
305
+ expect((_e = (_d = (_c = (_b = (_a = result === null || result === void 0 ? void 0 : result.current) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.conversation) === null || _c === void 0 ? void 0 : _c.smsMessages) === null || _d === void 0 ? void 0 : _d.edges) === null || _e === void 0 ? void 0 : _e.length).toBe(1);
306
+ }));
307
+ });
308
+ describe("when hook receives `update` but is currently searching a collection", () => {
309
+ it("should return the existing collection without adding the subscribed content", () => __awaiter(void 0, void 0, void 0, function* () {
310
+ var _a, _b, _c, _d, _e;
311
+ const searchTerm = "FooBar";
312
+ const { result, waitForNextUpdate } = (0, react_hooks_1.renderHook)(() => useCollectionQueryHookWithSubscriptionAndSearch(query, searchTerm), {
313
+ wrapper: (0, test_utilities_1.wrapper)([
314
+ (0, test_utilities_1.buildListRequestMock)(query, responseMock, "1", searchTerm),
315
+ (0, test_utilities_1.buildSubscriptionRequestMock)("1"),
316
+ ]),
317
+ });
318
+ // Wait for initial load
319
+ yield (0, react_hooks_1.act)(waitForNextUpdate);
320
+ // Wait for subscription
321
+ yield (0, react_hooks_1.act)(() => (0, test_utilities_1.wait)(200));
322
+ expect((_e = (_d = (_c = (_b = (_a = result === null || result === void 0 ? void 0 : result.current) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.conversation) === null || _c === void 0 ? void 0 : _c.smsMessages) === null || _d === void 0 ? void 0 : _d.edges) === null || _e === void 0 ? void 0 : _e.length).toBe(1);
323
+ }));
324
+ });
325
+ });
326
+ });
327
+ });
@@ -1 +1 @@
1
- export { useFocusTrap } from "./useFocusTrap.js";
1
+ export { useFocusTrap } from "./useFocusTrap";
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useFocusTrap = void 0;
4
- var useFocusTrap_js_1 = require("./useFocusTrap.js");
5
- Object.defineProperty(exports, "useFocusTrap", { enumerable: true, get: function () { return useFocusTrap_js_1.useFocusTrap; } });
4
+ var useFocusTrap_1 = require("./useFocusTrap");
5
+ Object.defineProperty(exports, "useFocusTrap", { enumerable: true, get: function () { return useFocusTrap_1.useFocusTrap; } });
@@ -0,0 +1 @@
1
+ export {};