@astral/mobx-query 1.5.0 → 1.6.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.
- package/AdaptableMap/AdaptableMap.d.ts +29 -0
- package/AdaptableMap/AdaptableMap.js +77 -0
- package/AdaptableMap/index.d.ts +1 -0
- package/AdaptableMap/index.js +1 -0
- package/AuxiliaryQuery/AuxiliaryQuery.d.ts +10 -10
- package/AuxiliaryQuery/AuxiliaryQuery.js +8 -8
- package/DataStorage/DataStorage.d.ts +8 -9
- package/DataStorage/DataStorage.js +9 -9
- package/InfiniteQuery/InfiniteQuery.d.ts +38 -25
- package/InfiniteQuery/InfiniteQuery.js +16 -13
- package/MobxQuery/MobxQuery.d.ts +34 -23
- package/MobxQuery/MobxQuery.js +84 -55
- package/Mutation/Mutation.d.ts +6 -6
- package/Mutation/Mutation.js +3 -3
- package/Query/Query.d.ts +32 -19
- package/Query/Query.js +12 -9
- package/QueryContainer/QueryContainer.d.ts +8 -8
- package/QueryContainer/QueryContainer.js +8 -8
- package/README.md +3 -3
- package/StatusStorage/StatusStorage.d.ts +5 -6
- package/StatusStorage/StatusStorage.js +6 -6
- package/StorageFactory/StorageFactory.d.ts +4 -8
- package/StorageFactory/StorageFactory.js +10 -10
- package/package.json +1 -1
- package/types.d.ts +1 -1
package/MobxQuery/MobxQuery.d.ts
CHANGED
|
@@ -3,28 +3,38 @@ import { type InfiniteExecutor, InfiniteQuery, type InfiniteQueryParams } from '
|
|
|
3
3
|
import { Mutation, type MutationExecutor, type MutationParams } from '../Mutation';
|
|
4
4
|
import type { CacheKey, FetchPolicy } from '../types';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Стандартный обработчик ошибки запроса,
|
|
7
7
|
* будет вызван, если при вызове sync не был передан отдельный onError параметр
|
|
8
8
|
*/
|
|
9
9
|
type OnError<TError = unknown> = (error: TError) => void;
|
|
10
10
|
type MobxQueryParams = {
|
|
11
|
+
/**
|
|
12
|
+
* Политика получения данных по умолчанию.
|
|
13
|
+
* @enum cache-first - данные сначала берутся из кеша, если их нет, тогда идет обращение к сети, ответ записывается в кэш
|
|
14
|
+
* @enum network-only - данные всегда берутся из сети, при этом ответ записывается в кэш
|
|
15
|
+
*/
|
|
11
16
|
fetchPolicy?: FetchPolicy;
|
|
17
|
+
/**
|
|
18
|
+
* обработчик ошибок по умолчанию
|
|
19
|
+
*/
|
|
12
20
|
onError?: OnError;
|
|
13
21
|
/**
|
|
14
|
-
*
|
|
22
|
+
* Флаг, отвечающий за автоматический запрос данных при обращении к полю data по умолчанию.
|
|
15
23
|
* @default false
|
|
16
24
|
*/
|
|
17
25
|
enabledAutoFetch?: boolean;
|
|
18
26
|
};
|
|
19
|
-
type CreateQueryParams<TResult, TError, TIsBackground extends boolean> = Omit<QueryParams<TResult, TError, TIsBackground>, 'dataStorage' | 'statusStorage' | 'backgroundStatusStorage'> & {
|
|
27
|
+
type CreateQueryParams<TResult, TError, TIsBackground extends boolean> = Omit<QueryParams<TResult, TError, TIsBackground>, 'dataStorage' | 'statusStorage' | 'backgroundStatusStorage' | 'submitValidity'> & {
|
|
20
28
|
/**
|
|
21
|
-
*
|
|
29
|
+
* Режим фонового обновления
|
|
30
|
+
* @default false
|
|
22
31
|
*/
|
|
23
32
|
isBackground?: TIsBackground;
|
|
24
33
|
};
|
|
25
|
-
type CreateInfiniteQueryParams<TResult, TError, TIsBackground extends boolean> = Omit<InfiniteQueryParams<TResult, TError, TIsBackground>, 'dataStorage' | 'statusStorage' | 'backgroundStatusStorage'> & {
|
|
34
|
+
type CreateInfiniteQueryParams<TResult, TError, TIsBackground extends boolean> = Omit<InfiniteQueryParams<TResult, TError, TIsBackground>, 'dataStorage' | 'statusStorage' | 'backgroundStatusStorage' | 'submitValidity'> & {
|
|
26
35
|
/**
|
|
27
|
-
*
|
|
36
|
+
* Режим фонового обновления
|
|
37
|
+
* @default false
|
|
28
38
|
*/
|
|
29
39
|
isBackground?: TIsBackground;
|
|
30
40
|
};
|
|
@@ -33,65 +43,66 @@ type CreateInfiniteQueryParams<TResult, TError, TIsBackground extends boolean> =
|
|
|
33
43
|
*/
|
|
34
44
|
export declare class MobxQuery<TDefaultError = void> {
|
|
35
45
|
/**
|
|
36
|
-
*
|
|
46
|
+
* Объект соответствия хешей ключей и их значений
|
|
37
47
|
*/
|
|
38
48
|
private keys;
|
|
39
49
|
/**
|
|
40
50
|
* Map соответствия хешей ключей к запомненным сторам
|
|
41
51
|
*/
|
|
42
|
-
private
|
|
52
|
+
private queriesMap;
|
|
43
53
|
/**
|
|
44
|
-
*
|
|
54
|
+
* Фабрика создания хранилищ данных для обычного Query
|
|
45
55
|
*/
|
|
46
56
|
private queryDataStorageFactory;
|
|
47
57
|
/**
|
|
48
|
-
*
|
|
58
|
+
* Фабрика создания хранилищ статусов между экземплярами Query и экземллярами Infinite Query.
|
|
49
59
|
*/
|
|
50
60
|
private statusStorageFactory;
|
|
51
61
|
/**
|
|
52
|
-
*
|
|
53
|
-
*/
|
|
54
|
-
private infiniteQueryDataStorageFactory;
|
|
55
|
-
/**
|
|
56
|
-
* стандартный обработчик ошибок, будет использован, если не передан другой
|
|
62
|
+
* Стандартный обработчик ошибок, будет использован, если не передан другой
|
|
57
63
|
*/
|
|
58
64
|
private readonly defaultErrorHandler?;
|
|
59
65
|
/**
|
|
60
|
-
*
|
|
66
|
+
* Стандартное поведение политики кеширования
|
|
61
67
|
*/
|
|
62
68
|
private readonly defaultFetchPolicy;
|
|
63
69
|
/**
|
|
64
|
-
*
|
|
70
|
+
* Флаг, отвечающий за автоматический запрос данных при обращении к полю data
|
|
65
71
|
* @default false
|
|
66
72
|
*/
|
|
67
73
|
private readonly defaultEnabledAutoFetch;
|
|
68
74
|
private serialize;
|
|
69
75
|
constructor({ onError, fetchPolicy, enabledAutoFetch, }?: MobxQueryParams);
|
|
70
76
|
/**
|
|
71
|
-
*
|
|
77
|
+
* Метод для инвалидации по списку ключей,
|
|
72
78
|
* предполагается использование из домена
|
|
73
79
|
*/
|
|
74
80
|
invalidate: (keysParts: CacheKey[]) => void;
|
|
81
|
+
private submitValidity;
|
|
75
82
|
/**
|
|
76
|
-
*
|
|
83
|
+
* Метод инвалидации всех query
|
|
77
84
|
*/
|
|
78
85
|
invalidateQueries: () => void;
|
|
79
86
|
/**
|
|
80
|
-
*
|
|
87
|
+
* Метод, который занимается проверкой наличия квери по ключу,
|
|
81
88
|
* и если нет, создает новый, добавляет его к себе в память, и возвращает его пользователю
|
|
82
89
|
*/
|
|
83
90
|
private getCachedQuery;
|
|
91
|
+
/**
|
|
92
|
+
* Метод для создания ключей к внутренним хранилищам
|
|
93
|
+
*/
|
|
94
|
+
private makeKeys;
|
|
84
95
|
private getBackgroundStatusStorage;
|
|
85
96
|
/**
|
|
86
|
-
*
|
|
97
|
+
* Метод создания стора, кешируется
|
|
87
98
|
*/
|
|
88
99
|
createQuery: <TResult, TError = TDefaultError, TIsBackground extends boolean = false>(key: CacheKey[], executor: QueryExecutor<TResult>, params?: CreateQueryParams<TResult, TError, TIsBackground> | undefined) => Query<TResult, TError, TIsBackground>;
|
|
89
100
|
/**
|
|
90
|
-
*
|
|
101
|
+
* Метод создания инфинит стора, кешируется
|
|
91
102
|
*/
|
|
92
103
|
createInfiniteQuery: <TResult, TError = TDefaultError, TIsBackground extends boolean = false>(key: CacheKey[], executor: InfiniteExecutor<TResult>, params?: CreateInfiniteQueryParams<TResult, TError, TIsBackground> | undefined) => InfiniteQuery<TResult, TError, TIsBackground>;
|
|
93
104
|
/**
|
|
94
|
-
*
|
|
105
|
+
* Метод создания мутации, не кешируется
|
|
95
106
|
*/
|
|
96
107
|
createMutation: <TResult, TError = TDefaultError, TExecutorParams = void>(executor: MutationExecutor<TResult, TExecutorParams>, params?: MutationParams<TResult, TError> | undefined) => Mutation<TResult, TError, TExecutorParams>;
|
|
97
108
|
}
|
package/MobxQuery/MobxQuery.js
CHANGED
|
@@ -3,8 +3,9 @@ import { InfiniteQuery, } from '../InfiniteQuery';
|
|
|
3
3
|
import { Mutation, } from '../Mutation';
|
|
4
4
|
import { DataStorageFactory } from '../DataStorage';
|
|
5
5
|
import { StatusStorageFactory } from '../StatusStorage';
|
|
6
|
+
import { AdaptableMap } from '../AdaptableMap';
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
+
* Время, спустя которое, запись о query c network-only будет удалена
|
|
8
9
|
*/
|
|
9
10
|
const DEFAULT_TIME_TO_CLEAN = 100;
|
|
10
11
|
/**
|
|
@@ -13,65 +14,87 @@ const DEFAULT_TIME_TO_CLEAN = 100;
|
|
|
13
14
|
export class MobxQuery {
|
|
14
15
|
constructor({ onError, fetchPolicy = 'cache-first', enabledAutoFetch = false, } = {}) {
|
|
15
16
|
/**
|
|
16
|
-
*
|
|
17
|
+
* Объект соответствия хешей ключей и их значений
|
|
17
18
|
*/
|
|
18
|
-
this.keys =
|
|
19
|
+
this.keys = new Map();
|
|
19
20
|
/**
|
|
20
21
|
* Map соответствия хешей ключей к запомненным сторам
|
|
21
22
|
*/
|
|
22
|
-
this.
|
|
23
|
+
this.queriesMap = new AdaptableMap();
|
|
23
24
|
/**
|
|
24
|
-
*
|
|
25
|
+
* Фабрика создания хранилищ данных для обычного Query
|
|
25
26
|
*/
|
|
26
27
|
this.queryDataStorageFactory = new DataStorageFactory();
|
|
27
28
|
/**
|
|
28
|
-
*
|
|
29
|
+
* Фабрика создания хранилищ статусов между экземплярами Query и экземллярами Infinite Query.
|
|
29
30
|
*/
|
|
30
31
|
this.statusStorageFactory = new StatusStorageFactory();
|
|
31
|
-
/**
|
|
32
|
-
* фабрика создания хранилищ данных для Infinite Query
|
|
33
|
-
*/
|
|
34
|
-
this.infiniteQueryDataStorageFactory = new DataStorageFactory();
|
|
35
32
|
this.serialize = (data) => JSON.stringify(data);
|
|
36
33
|
/**
|
|
37
|
-
*
|
|
34
|
+
* Метод для инвалидации по списку ключей,
|
|
38
35
|
* предполагается использование из домена
|
|
39
36
|
*/
|
|
40
37
|
this.invalidate = (keysParts) => {
|
|
41
|
-
//
|
|
38
|
+
// Сет сериализовонных ключей
|
|
42
39
|
const keysSet = new Set(keysParts.map(this.serialize));
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
[...this.keys.keys()].forEach((keyHash) => {
|
|
41
|
+
const key = this.keys.get(keyHash);
|
|
42
|
+
if (!key) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Проверяем, есть ли пересечение между закешированными ключами и набором ключей для инвалидации
|
|
46
|
+
const hasTouchedElement = key.some((valuePart) => keysSet.has(this.serialize(valuePart)));
|
|
48
47
|
if (hasTouchedElement) {
|
|
49
|
-
|
|
48
|
+
const query = this.queriesMap.get(keyHash);
|
|
49
|
+
if (query) {
|
|
50
|
+
query.invalidate();
|
|
51
|
+
// Конвертируем инвалидированный квери в слабый,
|
|
52
|
+
// чтобы сборщик мусора мог удалить неиспользуемые квери
|
|
53
|
+
this.queriesMap.convertToWeak(keyHash);
|
|
54
|
+
}
|
|
50
55
|
}
|
|
51
56
|
});
|
|
52
57
|
};
|
|
58
|
+
// Метод для подтверждения того, что квери успешно получил валидные данные
|
|
59
|
+
this.submitValidity = (keyHash) => {
|
|
60
|
+
// конвертируем квери в сильный,
|
|
61
|
+
// чтобы сборщик мусора не удалил наш кеш преждевременно
|
|
62
|
+
this.queriesMap.convertToStrong(keyHash);
|
|
63
|
+
};
|
|
53
64
|
/**
|
|
54
|
-
*
|
|
65
|
+
* Метод инвалидации всех query
|
|
55
66
|
*/
|
|
56
67
|
this.invalidateQueries = () => {
|
|
57
|
-
[...this.
|
|
58
|
-
|
|
68
|
+
[...this.keys.keys()].forEach((keyHash) => {
|
|
69
|
+
var _a;
|
|
70
|
+
(_a = this.queriesMap.get(keyHash)) === null || _a === void 0 ? void 0 : _a.invalidate();
|
|
71
|
+
this.queriesMap.convertToWeak(keyHash);
|
|
59
72
|
});
|
|
60
73
|
};
|
|
61
74
|
/**
|
|
62
|
-
*
|
|
75
|
+
* Метод, который занимается проверкой наличия квери по ключу,
|
|
63
76
|
* и если нет, создает новый, добавляет его к себе в память, и возвращает его пользователю
|
|
64
77
|
*/
|
|
65
|
-
this.getCachedQuery = (key,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
78
|
+
this.getCachedQuery = (key, createInstance, type, createParams) => {
|
|
79
|
+
var _a, _b;
|
|
80
|
+
const fetchPolicy = (createParams === null || createParams === void 0 ? void 0 : createParams.fetchPolicy) || this.defaultFetchPolicy;
|
|
81
|
+
const keys = this.makeKeys(key, fetchPolicy, (_a = createParams === null || createParams === void 0 ? void 0 : createParams.isBackground) !== null && _a !== void 0 ? _a : false, type);
|
|
82
|
+
const cachedQuery = this.queriesMap.get(keys.queryKeyHash);
|
|
83
|
+
if (cachedQuery) {
|
|
84
|
+
return cachedQuery;
|
|
71
85
|
}
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
86
|
+
const query = createInstance({
|
|
87
|
+
onError: ((createParams === null || createParams === void 0 ? void 0 : createParams.onError) ||
|
|
88
|
+
this.defaultErrorHandler),
|
|
89
|
+
enabledAutoFetch: (_b = createParams === null || createParams === void 0 ? void 0 : createParams.enabledAutoFetch) !== null && _b !== void 0 ? _b : this.defaultEnabledAutoFetch,
|
|
90
|
+
fetchPolicy: fetchPolicy,
|
|
91
|
+
dataStorage: this.queryDataStorageFactory.getStorage(keys.dataKeyHash),
|
|
92
|
+
statusStorage: this.statusStorageFactory.getStorage(keys.statusKeyHash),
|
|
93
|
+
backgroundStatusStorage: this.getBackgroundStatusStorage(keys.backgroundStatusKeyHash, Boolean(createParams === null || createParams === void 0 ? void 0 : createParams.isBackground)),
|
|
94
|
+
submitValidity: () => this.submitValidity(keys.queryKeyHash),
|
|
95
|
+
});
|
|
96
|
+
this.queriesMap.set(keys.queryKeyHash, query);
|
|
97
|
+
this.keys.set(keys.queryKeyHash, keys.queryKey);
|
|
75
98
|
// Ожидается, что network-only квери не должны кешироваться,
|
|
76
99
|
// но, с введением StrictMode в реакт 18, проявилась проблема,
|
|
77
100
|
// что network-only квери, созданные в одном реакт компоненте,
|
|
@@ -81,39 +104,45 @@ export class MobxQuery {
|
|
|
81
104
|
// делают по отдельному запросу к данным единомоментно,
|
|
82
105
|
if (fetchPolicy === 'network-only') {
|
|
83
106
|
setTimeout(() => {
|
|
84
|
-
this.
|
|
85
|
-
|
|
107
|
+
this.queriesMap.delete(keys.queryKeyHash);
|
|
108
|
+
this.keys.delete(keys.queryKeyHash);
|
|
86
109
|
}, DEFAULT_TIME_TO_CLEAN);
|
|
87
110
|
}
|
|
88
|
-
return
|
|
111
|
+
return query;
|
|
89
112
|
};
|
|
90
|
-
this.getBackgroundStatusStorage = (key, hasBackground) => (hasBackground
|
|
91
|
-
? this.statusStorageFactory.getStorage([...key, true])
|
|
92
|
-
: null);
|
|
93
113
|
/**
|
|
94
|
-
*
|
|
114
|
+
* Метод для создания ключей к внутренним хранилищам
|
|
95
115
|
*/
|
|
96
|
-
this.
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
116
|
+
this.makeKeys = (rootKey, fetchPolicy, isBackground, type) => {
|
|
117
|
+
const queryKey = [...rootKey, { fetchPolicy, isBackground, type }];
|
|
118
|
+
const queryKeyHash = this.serialize(queryKey);
|
|
119
|
+
const dataKeyHash = this.serialize([...rootKey, { type }]);
|
|
120
|
+
const statusKeyHash = this.serialize([...rootKey, { type }]);
|
|
121
|
+
const backgroundStatusKeyHash = this.serialize([
|
|
122
|
+
...rootKey,
|
|
123
|
+
{ type, isBackground },
|
|
124
|
+
]);
|
|
125
|
+
return {
|
|
126
|
+
queryKey,
|
|
127
|
+
queryKeyHash,
|
|
128
|
+
statusKeyHash,
|
|
129
|
+
backgroundStatusKeyHash,
|
|
130
|
+
dataKeyHash,
|
|
131
|
+
};
|
|
103
132
|
};
|
|
133
|
+
this.getBackgroundStatusStorage = (keyHash, hasBackground) => (hasBackground
|
|
134
|
+
? this.statusStorageFactory.getStorage(keyHash)
|
|
135
|
+
: null);
|
|
104
136
|
/**
|
|
105
|
-
*
|
|
137
|
+
* Метод создания стора, кешируется
|
|
106
138
|
*/
|
|
107
|
-
this.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
this.defaultErrorHandler), enabledAutoFetch: (_a = params === null || params === void 0 ? void 0 : params.enabledAutoFetch) !== null && _a !== void 0 ? _a : this.defaultEnabledAutoFetch, dataStorage: this.infiniteQueryDataStorageFactory.getStorage(key), statusStorage: this.statusStorageFactory.getStorage(key), fetchPolicy: fetchPolicy, backgroundStatusStorage: this.getBackgroundStatusStorage(key, Boolean(params === null || params === void 0 ? void 0 : params.isBackground)) }));
|
|
113
|
-
}, fetchPolicy);
|
|
114
|
-
};
|
|
139
|
+
this.createQuery = (key, executor, params) => this.getCachedQuery(key, (internalParams) => new Query(executor, Object.assign(Object.assign(Object.assign({}, params), internalParams), { dataStorage: internalParams.dataStorage })), Query.name, params);
|
|
140
|
+
/**
|
|
141
|
+
* Метод создания инфинит стора, кешируется
|
|
142
|
+
*/
|
|
143
|
+
this.createInfiniteQuery = (key, executor, params) => this.getCachedQuery(key, (internalParams) => new InfiniteQuery(executor, Object.assign(Object.assign(Object.assign({}, params), internalParams), { dataStorage: internalParams.dataStorage })), InfiniteQuery.name, params);
|
|
115
144
|
/**
|
|
116
|
-
*
|
|
145
|
+
* Метод создания мутации, не кешируется
|
|
117
146
|
*/
|
|
118
147
|
this.createMutation = (executor, params) => new Mutation(executor, Object.assign(Object.assign({}, params), { onError: (params === null || params === void 0 ? void 0 : params.onError) || this.defaultErrorHandler }));
|
|
119
148
|
this.defaultErrorHandler = onError;
|
package/Mutation/Mutation.d.ts
CHANGED
|
@@ -2,32 +2,32 @@ import { AuxiliaryQuery } from '../AuxiliaryQuery';
|
|
|
2
2
|
import type { QueryBaseActions, Sync, SyncParams } from '../types';
|
|
3
3
|
import { QueryContainer } from '../QueryContainer';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Исполнитель запроса
|
|
6
6
|
*/
|
|
7
7
|
export type MutationExecutor<TResult, TParams> = (params: TParams) => Promise<TResult>;
|
|
8
8
|
export type MutationParams<TResult, TError> = {
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Обработчик ошибки, вызываемый по умолчанию
|
|
11
11
|
*/
|
|
12
12
|
onError?: SyncParams<TResult, TError>['onError'];
|
|
13
13
|
};
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Простой квери для запросов, которые не требуют кэширования,
|
|
16
16
|
* пример - POST запросы
|
|
17
17
|
*/
|
|
18
18
|
export declare class Mutation<TResult, TError = void, TExecutorParams = void> extends QueryContainer<TError, AuxiliaryQuery<TResult, TError>, false> implements QueryBaseActions<TResult, TError, TExecutorParams> {
|
|
19
19
|
private readonly executor;
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* Обработчик ошибки, вызываемый по умолчанию
|
|
22
22
|
*/
|
|
23
23
|
private readonly defaultOnError?;
|
|
24
24
|
constructor(executor: MutationExecutor<TResult, TExecutorParams>, { onError }?: MutationParams<TResult, TError>);
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* Синхронный метод получения/отправки данных
|
|
27
27
|
*/
|
|
28
28
|
sync: Sync<TResult, TError, TExecutorParams>;
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* Асинхронный метод получения/отправки данных,
|
|
31
31
|
* предполагается, что нужно будет самостоятельно обрабатывать ошибку
|
|
32
32
|
*/
|
|
33
33
|
async: (params: TExecutorParams) => Promise<TResult>;
|
package/Mutation/Mutation.js
CHANGED
|
@@ -3,7 +3,7 @@ import { AuxiliaryQuery } from '../AuxiliaryQuery';
|
|
|
3
3
|
import { QueryContainer } from '../QueryContainer';
|
|
4
4
|
import { StatusStorage } from '../StatusStorage';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Простой квери для запросов, которые не требуют кэширования,
|
|
7
7
|
* пример - POST запросы
|
|
8
8
|
*/
|
|
9
9
|
export class Mutation extends QueryContainer {
|
|
@@ -12,7 +12,7 @@ export class Mutation extends QueryContainer {
|
|
|
12
12
|
super(statusStorage, null, new AuxiliaryQuery(statusStorage, null));
|
|
13
13
|
this.executor = executor;
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Синхронный метод получения/отправки данных
|
|
16
16
|
*/
|
|
17
17
|
this.sync = (options) => {
|
|
18
18
|
const { onSuccess, onError, params } = options || {};
|
|
@@ -32,7 +32,7 @@ export class Mutation extends QueryContainer {
|
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
35
|
+
* Асинхронный метод получения/отправки данных,
|
|
36
36
|
* предполагается, что нужно будет самостоятельно обрабатывать ошибку
|
|
37
37
|
*/
|
|
38
38
|
this.async = (params) => {
|
package/Query/Query.d.ts
CHANGED
|
@@ -4,84 +4,97 @@ import type { DataStorage } from '../DataStorage';
|
|
|
4
4
|
import { QueryContainer } from '../QueryContainer';
|
|
5
5
|
import { type StatusStorage } from '../StatusStorage';
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Исполнитель запроса
|
|
8
8
|
*/
|
|
9
9
|
export type QueryExecutor<TResult> = () => Promise<TResult>;
|
|
10
10
|
export type QueryParams<TResult, TError, TIsBackground extends boolean = false> = {
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Обработчик ошибки, вызываемый по умолчанию
|
|
13
13
|
*/
|
|
14
14
|
onError?: SyncParams<TResult, TError>['onError'];
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
16
|
+
* Флаг, отвечающий за автоматический запрос данных при обращении к полю data
|
|
17
17
|
*/
|
|
18
18
|
enabledAutoFetch?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Политика получения данных.
|
|
21
|
+
* @enum cache-first - данные сначала берутся из кеша, если их нет, тогда идет обращение к сети, ответ записывается в кэш
|
|
22
|
+
* @enum network-only - данные всегда берутся из сети, при этом ответ записывается в кэш
|
|
23
|
+
*/
|
|
19
24
|
fetchPolicy?: FetchPolicy;
|
|
20
25
|
/**
|
|
21
|
-
*
|
|
26
|
+
* Инстанс хранилища данных
|
|
22
27
|
*/
|
|
23
28
|
dataStorage: DataStorage<TResult>;
|
|
24
29
|
/**
|
|
25
|
-
*
|
|
30
|
+
* Инстанс хранилища основных статусов
|
|
26
31
|
*/
|
|
27
32
|
statusStorage: StatusStorage<TError>;
|
|
28
33
|
/**
|
|
29
|
-
*
|
|
34
|
+
* Инстанс хранилища фоновых статусов
|
|
30
35
|
*/
|
|
31
36
|
backgroundStatusStorage?: TIsBackground extends true ? StatusStorage<TError> : null | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Колбэк, вызываемый при успешном завершении запроса, подразумевается использование, для подтверждения валидности данных, чтобы квери не был удален из памяти
|
|
39
|
+
*/
|
|
40
|
+
submitValidity?: () => void;
|
|
32
41
|
};
|
|
33
42
|
/**
|
|
34
|
-
*
|
|
43
|
+
* Стор для работы с запросами,
|
|
35
44
|
* которые должны быть закешированы,
|
|
36
45
|
* но им не требуется усложнение в виде работы с фильтрами и инфинити запросами
|
|
37
46
|
*/
|
|
38
47
|
export declare class Query<TResult, TError = void, TIsBackground extends boolean = false> extends QueryContainer<TError, AuxiliaryQuery<TResult, TError>, TIsBackground> implements QueryBaseActions<TResult, TError, undefined> {
|
|
39
48
|
private readonly executor;
|
|
40
49
|
/**
|
|
41
|
-
*
|
|
50
|
+
* Хранилище данных, для обеспечения возможности синхронизации данных между разными инстансами
|
|
42
51
|
*/
|
|
43
52
|
private storage;
|
|
44
53
|
/**
|
|
45
|
-
*
|
|
54
|
+
* Обработчик ошибки, вызываемый по умолчанию
|
|
46
55
|
*/
|
|
47
56
|
private defaultOnError?;
|
|
48
57
|
/**
|
|
49
|
-
*
|
|
58
|
+
* Флаг, отвечающий за автоматический запрос данных при обращении к полю data
|
|
50
59
|
*/
|
|
51
60
|
private enabledAutoFetch?;
|
|
52
61
|
/**
|
|
53
|
-
*
|
|
62
|
+
* Стандартное поведение политики кеширования
|
|
54
63
|
*/
|
|
55
64
|
private readonly defaultFetchPolicy?;
|
|
56
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Колбэк, вызываемый при успешном завершении запроса, подразумевается использование, для подтверждения валидности данных, чтобы квери не был удален из памяти
|
|
67
|
+
*/
|
|
68
|
+
private readonly submitValidity?;
|
|
69
|
+
constructor(executor: QueryExecutor<TResult>, { onError, enabledAutoFetch, fetchPolicy, dataStorage, statusStorage, backgroundStatusStorage, submitValidity, }: QueryParams<TResult, TError, TIsBackground>);
|
|
57
70
|
private get isNetworkOnly();
|
|
58
71
|
/**
|
|
59
|
-
*
|
|
72
|
+
* Метод для инвалидации данных
|
|
60
73
|
*/
|
|
61
74
|
invalidate: () => void;
|
|
62
75
|
/**
|
|
63
|
-
*
|
|
76
|
+
* Синхронный метод получения данных
|
|
64
77
|
*/
|
|
65
78
|
sync: Sync<TResult, TError, undefined>;
|
|
66
79
|
/**
|
|
67
|
-
*
|
|
80
|
+
* Обработчик успешного ответа
|
|
68
81
|
*/
|
|
69
82
|
private submitSuccess;
|
|
70
83
|
/**
|
|
71
|
-
*
|
|
84
|
+
* Форс метод для установки данных
|
|
72
85
|
*/
|
|
73
86
|
forceUpdate: (data: TResult) => void;
|
|
74
87
|
/**
|
|
75
|
-
*
|
|
88
|
+
* Метод для переиспользования синхронной логики запроса
|
|
76
89
|
*/
|
|
77
90
|
protected proceedSync: Sync<TResult, TError>;
|
|
78
91
|
/**
|
|
79
|
-
*
|
|
92
|
+
* Асинхронный метод получения данных,
|
|
80
93
|
* предполагается, что нужно будет самостоятельно обрабатывать ошибку
|
|
81
94
|
*/
|
|
82
95
|
async: () => Promise<TResult>;
|
|
83
96
|
/**
|
|
84
|
-
*
|
|
97
|
+
* Содержит реактивные данные
|
|
85
98
|
* благодаря mobx, при изменении isInvalid, свойство будет вычисляться заново,
|
|
86
99
|
* следовательно, стриггерится условие невалидности,
|
|
87
100
|
* и начнется запрос, в результате которого, данные обновятся
|
package/Query/Query.js
CHANGED
|
@@ -2,22 +2,22 @@ import { action, computed, makeObservable, when } from 'mobx';
|
|
|
2
2
|
import { AuxiliaryQuery } from '../AuxiliaryQuery';
|
|
3
3
|
import { QueryContainer } from '../QueryContainer';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Стор для работы с запросами,
|
|
6
6
|
* которые должны быть закешированы,
|
|
7
7
|
* но им не требуется усложнение в виде работы с фильтрами и инфинити запросами
|
|
8
8
|
*/
|
|
9
9
|
export class Query extends QueryContainer {
|
|
10
|
-
constructor(executor, { onError, enabledAutoFetch, fetchPolicy, dataStorage, statusStorage, backgroundStatusStorage = null, }) {
|
|
10
|
+
constructor(executor, { onError, enabledAutoFetch, fetchPolicy, dataStorage, statusStorage, backgroundStatusStorage = null, submitValidity, }) {
|
|
11
11
|
super(statusStorage, backgroundStatusStorage, new AuxiliaryQuery(statusStorage, backgroundStatusStorage));
|
|
12
12
|
this.executor = executor;
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Метод для инвалидации данных
|
|
15
15
|
*/
|
|
16
16
|
this.invalidate = () => {
|
|
17
17
|
this.auxiliary.invalidate();
|
|
18
18
|
};
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Синхронный метод получения данных
|
|
21
21
|
*/
|
|
22
22
|
this.sync = (params) => {
|
|
23
23
|
const isInstanceAllow = !(this.isLoading || this.isSuccess);
|
|
@@ -26,21 +26,23 @@ export class Query extends QueryContainer {
|
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* Обработчик успешного ответа
|
|
30
30
|
*/
|
|
31
31
|
this.submitSuccess = (resData) => {
|
|
32
|
+
var _a;
|
|
32
33
|
this.storage.setData(resData);
|
|
34
|
+
(_a = this.submitValidity) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
33
35
|
return resData;
|
|
34
36
|
};
|
|
35
37
|
/**
|
|
36
|
-
*
|
|
38
|
+
* Форс метод для установки данных
|
|
37
39
|
*/
|
|
38
40
|
this.forceUpdate = (data) => {
|
|
39
41
|
this.auxiliary.submitSuccess();
|
|
40
42
|
this.submitSuccess(data);
|
|
41
43
|
};
|
|
42
44
|
/**
|
|
43
|
-
*
|
|
45
|
+
* Метод для переиспользования синхронной логики запроса
|
|
44
46
|
*/
|
|
45
47
|
this.proceedSync = (options) => {
|
|
46
48
|
const { onSuccess, onError } = options || {};
|
|
@@ -61,7 +63,7 @@ export class Query extends QueryContainer {
|
|
|
61
63
|
});
|
|
62
64
|
};
|
|
63
65
|
/**
|
|
64
|
-
*
|
|
66
|
+
* Асинхронный метод получения данных,
|
|
65
67
|
* предполагается, что нужно будет самостоятельно обрабатывать ошибку
|
|
66
68
|
*/
|
|
67
69
|
this.async = () => {
|
|
@@ -76,6 +78,7 @@ export class Query extends QueryContainer {
|
|
|
76
78
|
this.enabledAutoFetch = enabledAutoFetch;
|
|
77
79
|
this.defaultFetchPolicy = fetchPolicy;
|
|
78
80
|
this.storage = dataStorage;
|
|
81
|
+
this.submitValidity = submitValidity;
|
|
79
82
|
makeObservable(this, {
|
|
80
83
|
async: action,
|
|
81
84
|
sync: action,
|
|
@@ -88,7 +91,7 @@ export class Query extends QueryContainer {
|
|
|
88
91
|
return this.defaultFetchPolicy === 'network-only';
|
|
89
92
|
}
|
|
90
93
|
/**
|
|
91
|
-
*
|
|
94
|
+
* Содержит реактивные данные
|
|
92
95
|
* благодаря mobx, при изменении isInvalid, свойство будет вычисляться заново,
|
|
93
96
|
* следовательно, стриггерится условие невалидности,
|
|
94
97
|
* и начнется запрос, в результате которого, данные обновятся
|