@cratis/arc.react 18.7.6 → 18.7.8
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/dist/cjs/queries/for_useQuery/FakeQueryWithRequiredParameters.d.ts +18 -0
- package/dist/cjs/queries/for_useQuery/FakeQueryWithRequiredParameters.d.ts.map +1 -0
- package/dist/cjs/queries/for_useQuery/when_required_argument_changes.d.ts +2 -0
- package/dist/cjs/queries/for_useQuery/when_required_argument_changes.d.ts.map +1 -0
- package/dist/cjs/queries/for_useQuery/when_sorting_changes.d.ts +2 -0
- package/dist/cjs/queries/for_useQuery/when_sorting_changes.d.ts.map +1 -0
- package/dist/cjs/queries/for_useQueryWithPaging/when_paging_changes.d.ts +2 -0
- package/dist/cjs/queries/for_useQueryWithPaging/when_paging_changes.d.ts.map +1 -0
- package/dist/cjs/queries/for_useQueryWithPaging/when_required_argument_changes.d.ts +2 -0
- package/dist/cjs/queries/for_useQueryWithPaging/when_required_argument_changes.d.ts.map +1 -0
- package/dist/cjs/queries/useQuery.d.ts.map +1 -1
- package/dist/cjs/queries/useQuery.js +10 -22
- package/dist/cjs/queries/useQuery.js.map +1 -1
- package/dist/esm/queries/for_useQuery/FakeQueryWithRequiredParameters.d.ts +18 -0
- package/dist/esm/queries/for_useQuery/FakeQueryWithRequiredParameters.d.ts.map +1 -0
- package/dist/esm/queries/for_useQuery/FakeQueryWithRequiredParameters.js +13 -0
- package/dist/esm/queries/for_useQuery/FakeQueryWithRequiredParameters.js.map +1 -0
- package/dist/esm/queries/for_useQuery/when_required_argument_changes.d.ts +2 -0
- package/dist/esm/queries/for_useQuery/when_required_argument_changes.d.ts.map +1 -0
- package/dist/esm/queries/for_useQuery/when_required_argument_changes.js +37 -0
- package/dist/esm/queries/for_useQuery/when_required_argument_changes.js.map +1 -0
- package/dist/esm/queries/for_useQuery/when_sorting_changes.d.ts +2 -0
- package/dist/esm/queries/for_useQuery/when_sorting_changes.d.ts.map +1 -0
- package/dist/esm/queries/for_useQuery/when_sorting_changes.js +36 -0
- package/dist/esm/queries/for_useQuery/when_sorting_changes.js.map +1 -0
- package/dist/esm/queries/for_useQueryWithPaging/when_paging_changes.d.ts +2 -0
- package/dist/esm/queries/for_useQueryWithPaging/when_paging_changes.d.ts.map +1 -0
- package/dist/esm/queries/for_useQueryWithPaging/when_paging_changes.js +36 -0
- package/dist/esm/queries/for_useQueryWithPaging/when_paging_changes.js.map +1 -0
- package/dist/esm/queries/for_useQueryWithPaging/when_required_argument_changes.d.ts +2 -0
- package/dist/esm/queries/for_useQueryWithPaging/when_required_argument_changes.d.ts.map +1 -0
- package/dist/esm/queries/for_useQueryWithPaging/when_required_argument_changes.js +38 -0
- package/dist/esm/queries/for_useQueryWithPaging/when_required_argument_changes.js.map +1 -0
- package/dist/esm/queries/useQuery.d.ts.map +1 -1
- package/dist/esm/queries/useQuery.js +11 -23
- package/dist/esm/queries/useQuery.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/queries/for_useQuery/FakeQueryWithRequiredParameters.ts +30 -0
- package/queries/for_useQuery/when_required_argument_changes.ts +55 -0
- package/queries/for_useQuery/when_sorting_changes.ts +54 -0
- package/queries/for_useQueryWithPaging/when_paging_changes.ts +54 -0
- package/queries/for_useQueryWithPaging/when_required_argument_changes.ts +57 -0
- package/queries/useQuery.ts +10 -23
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cratis/arc.react",
|
|
3
|
-
"version": "18.7.
|
|
3
|
+
"version": "18.7.8",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Cratis",
|
|
6
6
|
"license": "MIT",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"up": "yarn g:up"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@cratis/arc": "18.7.
|
|
62
|
+
"@cratis/arc": "18.7.8",
|
|
63
63
|
"tsyringe": "^4.10.0"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { QueryFor } from '@cratis/arc/queries';
|
|
5
|
+
import { ParameterDescriptor } from '@cratis/arc/reflection';
|
|
6
|
+
|
|
7
|
+
export interface FakeQueryWithRequiredParametersResult {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface FakeQueryWithRequiredParametersArguments {
|
|
13
|
+
userId: string;
|
|
14
|
+
category: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class FakeQueryWithRequiredParameters extends QueryFor<FakeQueryWithRequiredParametersResult[]> {
|
|
18
|
+
readonly route = '/api/fake-query-with-required-parameters';
|
|
19
|
+
readonly parameterDescriptors: ParameterDescriptor[] = [];
|
|
20
|
+
|
|
21
|
+
get requiredRequestParameters(): string[] {
|
|
22
|
+
return ['userId', 'category'];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
defaultValue: FakeQueryWithRequiredParametersResult[] = [];
|
|
26
|
+
|
|
27
|
+
constructor() {
|
|
28
|
+
super(Object, true);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { renderHook, waitFor } from '@testing-library/react';
|
|
6
|
+
import sinon from 'sinon';
|
|
7
|
+
import { useQuery } from '../useQuery';
|
|
8
|
+
import { FakeQueryWithRequiredParameters, FakeQueryWithRequiredParametersArguments } from './FakeQueryWithRequiredParameters';
|
|
9
|
+
import { ArcContext, ArcConfiguration } from '../../ArcContext';
|
|
10
|
+
import { createFetchHelper } from '@cratis/arc/helpers/fetchHelper';
|
|
11
|
+
|
|
12
|
+
describe('when required argument changes', () => {
|
|
13
|
+
let fetchStub: sinon.SinonStub;
|
|
14
|
+
let fetchHelper: { stubFetch: () => sinon.SinonStub; restore: () => void };
|
|
15
|
+
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
fetchHelper = createFetchHelper();
|
|
18
|
+
fetchStub = fetchHelper.stubFetch();
|
|
19
|
+
fetchStub.resolves({
|
|
20
|
+
json: async () => ({ data: [], isSuccess: true, isAuthorized: true, isValid: true, hasExceptions: false, validationResults: [], exceptionMessages: [], exceptionStackTrace: '' })
|
|
21
|
+
} as Response);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
fetchHelper.restore();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const config: ArcConfiguration = {
|
|
29
|
+
microservice: 'test-microservice',
|
|
30
|
+
apiBasePath: '/api',
|
|
31
|
+
origin: 'https://example.com'
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
35
|
+
React.createElement(ArcContext.Provider, { value: config }, children)
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
it('should execute query again when argument changes', async () => {
|
|
39
|
+
const { rerender } = renderHook(
|
|
40
|
+
({ args }: { args: FakeQueryWithRequiredParametersArguments }) => useQuery(FakeQueryWithRequiredParameters, args),
|
|
41
|
+
{
|
|
42
|
+
wrapper,
|
|
43
|
+
initialProps: { args: { userId: 'user-1', category: 'cat-1' } }
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
await waitFor(() => fetchStub.should.have.been.calledOnce);
|
|
48
|
+
|
|
49
|
+
fetchStub.resetHistory();
|
|
50
|
+
|
|
51
|
+
rerender({ args: { userId: 'user-2', category: 'cat-1' } });
|
|
52
|
+
|
|
53
|
+
await waitFor(() => fetchStub.should.have.been.calledOnce);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { renderHook, waitFor } from '@testing-library/react';
|
|
6
|
+
import sinon from 'sinon';
|
|
7
|
+
import { useQuery } from '../useQuery';
|
|
8
|
+
import { FakeQuery } from './FakeQuery';
|
|
9
|
+
import { ArcContext, ArcConfiguration } from '../../ArcContext';
|
|
10
|
+
import { createFetchHelper } from '@cratis/arc/helpers/fetchHelper';
|
|
11
|
+
import { Sorting, SortDirection } from '@cratis/arc/queries';
|
|
12
|
+
|
|
13
|
+
describe('when sorting changes', () => {
|
|
14
|
+
let fetchStub: sinon.SinonStub;
|
|
15
|
+
let fetchHelper: { stubFetch: () => sinon.SinonStub; restore: () => void };
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
fetchHelper = createFetchHelper();
|
|
19
|
+
fetchStub = fetchHelper.stubFetch();
|
|
20
|
+
fetchStub.resolves({
|
|
21
|
+
json: async () => ({ data: [], isSuccess: true, isAuthorized: true, isValid: true, hasExceptions: false, validationResults: [], exceptionMessages: [], exceptionStackTrace: '' })
|
|
22
|
+
} as Response);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
fetchHelper.restore();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const config: ArcConfiguration = {
|
|
30
|
+
microservice: 'test-microservice',
|
|
31
|
+
apiBasePath: '/api',
|
|
32
|
+
origin: 'https://example.com'
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
36
|
+
React.createElement(ArcContext.Provider, { value: config }, children)
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
it('should execute query again when sorting changes', async () => {
|
|
40
|
+
const { result } = renderHook(
|
|
41
|
+
() => useQuery(FakeQuery),
|
|
42
|
+
{ wrapper }
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
await waitFor(() => fetchStub.should.have.been.calledOnce);
|
|
46
|
+
|
|
47
|
+
fetchStub.resetHistory();
|
|
48
|
+
|
|
49
|
+
const [, , setSorting] = result.current;
|
|
50
|
+
await setSorting(new Sorting('name', SortDirection.ascending));
|
|
51
|
+
|
|
52
|
+
await waitFor(() => fetchStub.should.have.been.calledOnce);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { renderHook, waitFor } from '@testing-library/react';
|
|
6
|
+
import sinon from 'sinon';
|
|
7
|
+
import { useQueryWithPaging } from '../useQuery';
|
|
8
|
+
import { FakeQuery } from '../for_useQuery/FakeQuery';
|
|
9
|
+
import { ArcContext, ArcConfiguration } from '../../ArcContext';
|
|
10
|
+
import { createFetchHelper } from '@cratis/arc/helpers/fetchHelper';
|
|
11
|
+
import { Paging } from '@cratis/arc/queries';
|
|
12
|
+
|
|
13
|
+
describe('when paging changes', () => {
|
|
14
|
+
let fetchStub: sinon.SinonStub;
|
|
15
|
+
let fetchHelper: { stubFetch: () => sinon.SinonStub; restore: () => void };
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
fetchHelper = createFetchHelper();
|
|
19
|
+
fetchStub = fetchHelper.stubFetch();
|
|
20
|
+
fetchStub.resolves({
|
|
21
|
+
json: async () => ({ data: [], isSuccess: true, isAuthorized: true, isValid: true, hasExceptions: false, validationResults: [], exceptionMessages: [], exceptionStackTrace: '' })
|
|
22
|
+
} as Response);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
fetchHelper.restore();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const config: ArcConfiguration = {
|
|
30
|
+
microservice: 'test-microservice',
|
|
31
|
+
apiBasePath: '/api',
|
|
32
|
+
origin: 'https://example.com'
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
36
|
+
React.createElement(ArcContext.Provider, { value: config }, children)
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
it('should execute query again when page changes', async () => {
|
|
40
|
+
const { result } = renderHook(
|
|
41
|
+
() => useQueryWithPaging(FakeQuery, new Paging(0, 10)),
|
|
42
|
+
{ wrapper }
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
await waitFor(() => fetchStub.should.have.been.calledOnce);
|
|
46
|
+
|
|
47
|
+
fetchStub.resetHistory();
|
|
48
|
+
|
|
49
|
+
const [, , , setPage] = result.current;
|
|
50
|
+
await setPage(1);
|
|
51
|
+
|
|
52
|
+
await waitFor(() => fetchStub.should.have.been.calledOnce);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { renderHook, waitFor } from '@testing-library/react';
|
|
6
|
+
import sinon from 'sinon';
|
|
7
|
+
import { useQueryWithPaging } from '../useQuery';
|
|
8
|
+
import { FakeQueryWithRequiredParameters, FakeQueryWithRequiredParametersArguments } from '../for_useQuery/FakeQueryWithRequiredParameters';
|
|
9
|
+
import { ArcContext, ArcConfiguration } from '../../ArcContext';
|
|
10
|
+
import { createFetchHelper } from '@cratis/arc/helpers/fetchHelper';
|
|
11
|
+
import { Paging } from '@cratis/arc/queries';
|
|
12
|
+
|
|
13
|
+
describe('when required argument changes', () => {
|
|
14
|
+
let fetchStub: sinon.SinonStub;
|
|
15
|
+
let fetchHelper: { stubFetch: () => sinon.SinonStub; restore: () => void };
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
fetchHelper = createFetchHelper();
|
|
19
|
+
fetchStub = fetchHelper.stubFetch();
|
|
20
|
+
fetchStub.resolves({
|
|
21
|
+
json: async () => ({ data: [], isSuccess: true, isAuthorized: true, isValid: true, hasExceptions: false, validationResults: [], exceptionMessages: [], exceptionStackTrace: '' })
|
|
22
|
+
} as Response);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
fetchHelper.restore();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const config: ArcConfiguration = {
|
|
30
|
+
microservice: 'test-microservice',
|
|
31
|
+
apiBasePath: '/api',
|
|
32
|
+
origin: 'https://example.com'
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
|
36
|
+
React.createElement(ArcContext.Provider, { value: config }, children)
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
it('should execute query again when argument changes', async () => {
|
|
40
|
+
const { rerender } = renderHook(
|
|
41
|
+
({ args }: { args: FakeQueryWithRequiredParametersArguments }) =>
|
|
42
|
+
useQueryWithPaging(FakeQueryWithRequiredParameters, new Paging(0, 10), args),
|
|
43
|
+
{
|
|
44
|
+
wrapper,
|
|
45
|
+
initialProps: { args: { userId: 'user-1', category: 'cat-1' } }
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
await waitFor(() => fetchStub.should.have.been.calledOnce);
|
|
50
|
+
|
|
51
|
+
fetchStub.resetHistory();
|
|
52
|
+
|
|
53
|
+
rerender({ args: { userId: 'user-2', category: 'cat-1' } });
|
|
54
|
+
|
|
55
|
+
await waitFor(() => fetchStub.should.have.been.calledOnce);
|
|
56
|
+
});
|
|
57
|
+
});
|
package/queries/useQuery.ts
CHANGED
|
@@ -18,24 +18,24 @@ type QueryPerformer<TQuery extends IQueryFor<TDataType>, TDataType, TArguments =
|
|
|
18
18
|
|
|
19
19
|
function useQueryInternal<TDataType, TQuery extends IQueryFor<TDataType>, TArguments = object>(query: Constructor<TQuery>, performer: QueryPerformer<TQuery, TDataType, TArguments>, sorting?: Sorting, paging?: Paging, args?: TArguments):
|
|
20
20
|
[QueryResultWithState<TDataType>, PerformQuery<TArguments>, SetSorting, SetPage, SetPageSize] {
|
|
21
|
-
paging
|
|
22
|
-
sorting
|
|
21
|
+
const [currentPaging, setCurrentPaging] = useState<Paging>(paging ?? Paging.noPaging);
|
|
22
|
+
const [currentSorting, setCurrentSorting] = useState<Sorting>(sorting ?? Sorting.none);
|
|
23
23
|
const arc = useContext(ArcContext);
|
|
24
24
|
const queryInstance = useRef<TQuery | null>(null);
|
|
25
|
-
const [renderCounter, setRenderCounter] = useState(0);
|
|
26
25
|
|
|
27
26
|
queryInstance.current = useMemo(() => {
|
|
28
27
|
const instance = new query() as TQuery;
|
|
29
|
-
instance.paging =
|
|
30
|
-
instance.sorting =
|
|
28
|
+
instance.paging = currentPaging;
|
|
29
|
+
instance.sorting = currentSorting;
|
|
31
30
|
instance.setMicroservice(arc.microservice);
|
|
32
31
|
instance.setApiBasePath(arc.apiBasePath ?? '');
|
|
33
32
|
instance.setOrigin(arc.origin ?? '');
|
|
34
33
|
instance.setHttpHeadersCallback(arc.httpHeadersCallback ?? (() => ({})));
|
|
35
34
|
return instance;
|
|
36
|
-
}, []);
|
|
35
|
+
}, [currentPaging, currentSorting, arc.microservice, arc.apiBasePath, arc.origin]);
|
|
37
36
|
|
|
38
37
|
const [result, setResult] = useState<QueryResultWithState<TDataType>>(QueryResultWithState.initial(queryInstance.current!.defaultValue));
|
|
38
|
+
const argumentsDependency = queryInstance.current!.requiredRequestParameters.map(_ => args?.[_]);
|
|
39
39
|
|
|
40
40
|
const queryExecutor = (async (args?: TArguments) => {
|
|
41
41
|
if (queryInstance) {
|
|
@@ -50,11 +50,7 @@ function useQueryInternal<TDataType, TQuery extends IQueryFor<TDataType>, TArgum
|
|
|
50
50
|
|
|
51
51
|
useEffect(() => {
|
|
52
52
|
queryExecutor(args);
|
|
53
|
-
}, []);
|
|
54
|
-
|
|
55
|
-
const invalidate = () => {
|
|
56
|
-
setRenderCounter(renderCounter + 1);
|
|
57
|
-
};
|
|
53
|
+
}, [...argumentsDependency, ...[currentPaging, currentSorting]]);
|
|
58
54
|
|
|
59
55
|
return [
|
|
60
56
|
result!,
|
|
@@ -63,22 +59,13 @@ function useQueryInternal<TDataType, TQuery extends IQueryFor<TDataType>, TArgum
|
|
|
63
59
|
await queryExecutor(args);
|
|
64
60
|
},
|
|
65
61
|
async (sorting: Sorting) => {
|
|
66
|
-
|
|
67
|
-
queryInstance.current!.sorting = sorting;
|
|
68
|
-
invalidate();
|
|
69
|
-
await queryExecutor(args);
|
|
62
|
+
setCurrentSorting(sorting);
|
|
70
63
|
},
|
|
71
64
|
async (page: number) => {
|
|
72
|
-
|
|
73
|
-
queryInstance.current!.paging = new Paging(page, queryInstance.current!.paging?.pageSize ?? 0);
|
|
74
|
-
invalidate();
|
|
75
|
-
await queryExecutor(args);
|
|
65
|
+
setCurrentPaging(new Paging(page, currentPaging.pageSize));
|
|
76
66
|
},
|
|
77
67
|
async (pageSize: number) => {
|
|
78
|
-
|
|
79
|
-
queryInstance.current!.paging = new Paging(queryInstance.current!.paging?.page ?? 0, pageSize);
|
|
80
|
-
invalidate();
|
|
81
|
-
await queryExecutor(args);
|
|
68
|
+
setCurrentPaging(new Paging(currentPaging.page, pageSize));
|
|
82
69
|
}];
|
|
83
70
|
}
|
|
84
71
|
|