@trackunit/react-graphql-hooks 2.3.3 → 2.3.6
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.
- package/index.cjs.js +76 -1
- package/index.esm.js +76 -2
- package/migrations/entry.js.map +1 -0
- package/package.json +4 -4
- package/src/index.d.ts +1 -0
- package/src/useConnectionPageMerger.d.ts +17 -0
- package/src/utils/mergeConnectionPages.d.ts +23 -0
package/index.cjs.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
require('react/jsx-runtime');
|
|
4
4
|
var i18nLibraryTranslation = require('@trackunit/i18n-library-translation');
|
|
5
|
+
var react = require('react');
|
|
5
6
|
var client = require('@apollo/client');
|
|
6
7
|
var esToolkit = require('es-toolkit');
|
|
7
|
-
var react = require('react');
|
|
8
8
|
var reactComponents = require('@trackunit/react-components');
|
|
9
9
|
var sharedUtils = require('@trackunit/shared-utils');
|
|
10
10
|
|
|
@@ -50,6 +50,80 @@ const setupLibraryTranslations = () => {
|
|
|
50
50
|
i18nLibraryTranslation.registerTranslations(translations);
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
54
|
+
const toRelayPageInfo = (pageInfo) => {
|
|
55
|
+
if (!isRecord(pageInfo)) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
hasNextPage: pageInfo.hasNextPage === true,
|
|
60
|
+
hasPreviousPage: pageInfo.hasPreviousPage === true,
|
|
61
|
+
startCursor: typeof pageInfo.startCursor === "string" ? pageInfo.startCursor : null,
|
|
62
|
+
endCursor: typeof pageInfo.endCursor === "string" ? pageInfo.endCursor : null,
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
const readConnection = (data, rootField, connectionField) => {
|
|
66
|
+
if (!isRecord(data)) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const root = data[rootField];
|
|
70
|
+
if (!isRecord(root)) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const connection = root[connectionField];
|
|
74
|
+
return isRecord(connection) ? connection : null;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Appends a newly fetched Relay connection page to the accumulated one.
|
|
78
|
+
*
|
|
79
|
+
* Backs `useConnectionPageMerger`, which is how consumers reach this. A later page that comes back
|
|
80
|
+
* without `edges` (the field is nullable in most schemas) keeps everything accumulated so far
|
|
81
|
+
* instead of collapsing the list.
|
|
82
|
+
*
|
|
83
|
+
* @param rootField name of the field on the query root that holds the connection
|
|
84
|
+
* @param connectionField name of the connection field on the root field
|
|
85
|
+
* @param previous the accumulated query result, undefined on the first page
|
|
86
|
+
* @param newData the freshly fetched query result
|
|
87
|
+
* @returns {object} the merged result together with the newest page info
|
|
88
|
+
*/
|
|
89
|
+
const mergeConnectionPages = (rootField, connectionField, previous, newData) => {
|
|
90
|
+
const newConnection = readConnection(newData, rootField, connectionField);
|
|
91
|
+
const previousConnection = readConnection(previous, rootField, connectionField);
|
|
92
|
+
const pageInfo = toRelayPageInfo(newConnection?.pageInfo);
|
|
93
|
+
const previousEdges = previousConnection?.edges;
|
|
94
|
+
const root = newData[rootField];
|
|
95
|
+
if (newConnection === null || !isRecord(root) || !Array.isArray(previousEdges)) {
|
|
96
|
+
return { data: newData, pageInfo };
|
|
97
|
+
}
|
|
98
|
+
const newEdges = Array.isArray(newConnection.edges) ? newConnection.edges : [];
|
|
99
|
+
return {
|
|
100
|
+
data: {
|
|
101
|
+
...newData,
|
|
102
|
+
[rootField]: {
|
|
103
|
+
...root,
|
|
104
|
+
[connectionField]: {
|
|
105
|
+
...newConnection,
|
|
106
|
+
edges: [...previousEdges, ...newEdges],
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
pageInfo,
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Builds a stable `updateQuery` for `usePaginationQuery` that appends each fetched page of a Relay
|
|
116
|
+
* connection to the accumulated one.
|
|
117
|
+
*
|
|
118
|
+
* Use it when the connection sits at a fixed `<rootField>.<connectionField>` path. A later page that
|
|
119
|
+
* comes back without `edges` keeps everything accumulated so far instead of collapsing the list.
|
|
120
|
+
*
|
|
121
|
+
* @param rootField name of the field on the query root that holds the connection
|
|
122
|
+
* @param connectionField name of the connection field on the root field
|
|
123
|
+
* @returns {Function} the `updateQuery` callback
|
|
124
|
+
*/
|
|
125
|
+
const useConnectionPageMerger = (rootField, connectionField) => react.useCallback((previous, newData) => mergeConnectionPages(rootField, connectionField, previous, newData), [rootField, connectionField]);
|
|
126
|
+
|
|
53
127
|
/**
|
|
54
128
|
* A wrapper around Apollo Client's useLazyQuery that provides stable data by default.
|
|
55
129
|
*
|
|
@@ -624,6 +698,7 @@ const useQuery = (document, options) => {
|
|
|
624
698
|
*/
|
|
625
699
|
setupLibraryTranslations();
|
|
626
700
|
|
|
701
|
+
exports.useConnectionPageMerger = useConnectionPageMerger;
|
|
627
702
|
exports.useLazyQuery = useLazyQuery;
|
|
628
703
|
exports.usePaginationQuery = usePaginationQuery;
|
|
629
704
|
exports.useQuery = useQuery;
|
package/index.esm.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import 'react/jsx-runtime';
|
|
2
2
|
import { registerTranslations } from '@trackunit/i18n-library-translation';
|
|
3
|
+
import { useCallback, useMemo, useState, useReducer, useRef, useEffect } from 'react';
|
|
3
4
|
import { useLazyQuery as useLazyQuery$1, NetworkStatus, useQuery as useQuery$1 } from '@apollo/client';
|
|
4
5
|
import { omit, isEqual } from 'es-toolkit';
|
|
5
|
-
import { useMemo, useState, useReducer, useRef, useEffect, useCallback } from 'react';
|
|
6
6
|
import { defaultPageSize, useRelayPagination, useWatch } from '@trackunit/react-components';
|
|
7
7
|
import { truthy, objectKeys } from '@trackunit/shared-utils';
|
|
8
8
|
|
|
@@ -48,6 +48,80 @@ const setupLibraryTranslations = () => {
|
|
|
48
48
|
registerTranslations(translations);
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
52
|
+
const toRelayPageInfo = (pageInfo) => {
|
|
53
|
+
if (!isRecord(pageInfo)) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
hasNextPage: pageInfo.hasNextPage === true,
|
|
58
|
+
hasPreviousPage: pageInfo.hasPreviousPage === true,
|
|
59
|
+
startCursor: typeof pageInfo.startCursor === "string" ? pageInfo.startCursor : null,
|
|
60
|
+
endCursor: typeof pageInfo.endCursor === "string" ? pageInfo.endCursor : null,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
const readConnection = (data, rootField, connectionField) => {
|
|
64
|
+
if (!isRecord(data)) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
const root = data[rootField];
|
|
68
|
+
if (!isRecord(root)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const connection = root[connectionField];
|
|
72
|
+
return isRecord(connection) ? connection : null;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Appends a newly fetched Relay connection page to the accumulated one.
|
|
76
|
+
*
|
|
77
|
+
* Backs `useConnectionPageMerger`, which is how consumers reach this. A later page that comes back
|
|
78
|
+
* without `edges` (the field is nullable in most schemas) keeps everything accumulated so far
|
|
79
|
+
* instead of collapsing the list.
|
|
80
|
+
*
|
|
81
|
+
* @param rootField name of the field on the query root that holds the connection
|
|
82
|
+
* @param connectionField name of the connection field on the root field
|
|
83
|
+
* @param previous the accumulated query result, undefined on the first page
|
|
84
|
+
* @param newData the freshly fetched query result
|
|
85
|
+
* @returns {object} the merged result together with the newest page info
|
|
86
|
+
*/
|
|
87
|
+
const mergeConnectionPages = (rootField, connectionField, previous, newData) => {
|
|
88
|
+
const newConnection = readConnection(newData, rootField, connectionField);
|
|
89
|
+
const previousConnection = readConnection(previous, rootField, connectionField);
|
|
90
|
+
const pageInfo = toRelayPageInfo(newConnection?.pageInfo);
|
|
91
|
+
const previousEdges = previousConnection?.edges;
|
|
92
|
+
const root = newData[rootField];
|
|
93
|
+
if (newConnection === null || !isRecord(root) || !Array.isArray(previousEdges)) {
|
|
94
|
+
return { data: newData, pageInfo };
|
|
95
|
+
}
|
|
96
|
+
const newEdges = Array.isArray(newConnection.edges) ? newConnection.edges : [];
|
|
97
|
+
return {
|
|
98
|
+
data: {
|
|
99
|
+
...newData,
|
|
100
|
+
[rootField]: {
|
|
101
|
+
...root,
|
|
102
|
+
[connectionField]: {
|
|
103
|
+
...newConnection,
|
|
104
|
+
edges: [...previousEdges, ...newEdges],
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
pageInfo,
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Builds a stable `updateQuery` for `usePaginationQuery` that appends each fetched page of a Relay
|
|
114
|
+
* connection to the accumulated one.
|
|
115
|
+
*
|
|
116
|
+
* Use it when the connection sits at a fixed `<rootField>.<connectionField>` path. A later page that
|
|
117
|
+
* comes back without `edges` keeps everything accumulated so far instead of collapsing the list.
|
|
118
|
+
*
|
|
119
|
+
* @param rootField name of the field on the query root that holds the connection
|
|
120
|
+
* @param connectionField name of the connection field on the root field
|
|
121
|
+
* @returns {Function} the `updateQuery` callback
|
|
122
|
+
*/
|
|
123
|
+
const useConnectionPageMerger = (rootField, connectionField) => useCallback((previous, newData) => mergeConnectionPages(rootField, connectionField, previous, newData), [rootField, connectionField]);
|
|
124
|
+
|
|
51
125
|
/**
|
|
52
126
|
* A wrapper around Apollo Client's useLazyQuery that provides stable data by default.
|
|
53
127
|
*
|
|
@@ -622,4 +696,4 @@ const useQuery = (document, options) => {
|
|
|
622
696
|
*/
|
|
623
697
|
setupLibraryTranslations();
|
|
624
698
|
|
|
625
|
-
export { useLazyQuery, usePaginationQuery, useQuery };
|
|
699
|
+
export { useConnectionPageMerger, useLazyQuery, usePaginationQuery, useQuery };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../../../libs/react/graphql-hooks/migrations/entry.ts"],"names":[],"mappings":"","sourcesContent":["export {};\n"]}
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-graphql-hooks",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.6",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=24.x"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@trackunit/i18n-library-translation": "2.2.
|
|
11
|
-
"@trackunit/shared-utils": "1.15.
|
|
10
|
+
"@trackunit/i18n-library-translation": "2.2.5",
|
|
11
|
+
"@trackunit/shared-utils": "1.15.93",
|
|
12
12
|
"es-toolkit": "^1.39.10",
|
|
13
|
-
"@trackunit/react-components": "2.
|
|
13
|
+
"@trackunit/react-components": "2.4.0"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
16
|
"@apollo/client": "^3.13.8",
|
package/src/index.d.ts
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { RelayPageInfo } from "@trackunit/react-components";
|
|
2
|
+
import { ConnectionQueryShape } from "./utils/mergeConnectionPages";
|
|
3
|
+
/**
|
|
4
|
+
* Builds a stable `updateQuery` for `usePaginationQuery` that appends each fetched page of a Relay
|
|
5
|
+
* connection to the accumulated one.
|
|
6
|
+
*
|
|
7
|
+
* Use it when the connection sits at a fixed `<rootField>.<connectionField>` path. A later page that
|
|
8
|
+
* comes back without `edges` keeps everything accumulated so far instead of collapsing the list.
|
|
9
|
+
*
|
|
10
|
+
* @param rootField name of the field on the query root that holds the connection
|
|
11
|
+
* @param connectionField name of the connection field on the root field
|
|
12
|
+
* @returns {Function} the `updateQuery` callback
|
|
13
|
+
*/
|
|
14
|
+
export declare const useConnectionPageMerger: <TRootField extends string, TQuery extends ConnectionQueryShape<TRootField>>(rootField: TRootField, connectionField: string) => ((previous: TQuery | undefined, newData: TQuery) => {
|
|
15
|
+
data: TQuery;
|
|
16
|
+
pageInfo: RelayPageInfo | null;
|
|
17
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { RelayPageInfo } from "@trackunit/react-components";
|
|
2
|
+
export type ConnectionQueryShape<TRootField extends string> = {
|
|
3
|
+
[K in TRootField]?: {
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
} | null;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Appends a newly fetched Relay connection page to the accumulated one.
|
|
9
|
+
*
|
|
10
|
+
* Backs `useConnectionPageMerger`, which is how consumers reach this. A later page that comes back
|
|
11
|
+
* without `edges` (the field is nullable in most schemas) keeps everything accumulated so far
|
|
12
|
+
* instead of collapsing the list.
|
|
13
|
+
*
|
|
14
|
+
* @param rootField name of the field on the query root that holds the connection
|
|
15
|
+
* @param connectionField name of the connection field on the root field
|
|
16
|
+
* @param previous the accumulated query result, undefined on the first page
|
|
17
|
+
* @param newData the freshly fetched query result
|
|
18
|
+
* @returns {object} the merged result together with the newest page info
|
|
19
|
+
*/
|
|
20
|
+
export declare const mergeConnectionPages: <TRootField extends string, TQuery extends ConnectionQueryShape<TRootField>>(rootField: TRootField, connectionField: string, previous: TQuery | undefined, newData: TQuery) => {
|
|
21
|
+
data: TQuery;
|
|
22
|
+
pageInfo: RelayPageInfo | null;
|
|
23
|
+
};
|