@astral/mobx-query 1.6.1 → 1.7.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.
@@ -30,7 +30,7 @@ export declare class AuxiliaryQuery<TResult, TError = void> {
30
30
  * Метод ответственный за создание единого промиса,
31
31
  * для устранения гонки запросов
32
32
  */
33
- getUnifiedPromise: (executor: Executor<TResult>) => Promise<TResult>;
33
+ getUnifiedPromise: (executor: Executor<TResult>, onSuccess?: ((data: TResult) => void) | undefined) => Promise<TResult>;
34
34
  private setSuccess;
35
35
  private checkBackgroundAndSet;
36
36
  /**
@@ -22,13 +22,14 @@ export class AuxiliaryQuery {
22
22
  * Метод ответственный за создание единого промиса,
23
23
  * для устранения гонки запросов
24
24
  */
25
- this.getUnifiedPromise = (executor) => {
25
+ this.getUnifiedPromise = (executor, onSuccess) => {
26
26
  // проверяем, если синглтона нет, то надо создать
27
27
  if (!Boolean(this.unifiedPromise)) {
28
28
  this.startLoading();
29
29
  this.unifiedPromise = executor()
30
30
  .then((resData) => {
31
31
  runInAction(this.submitSuccess);
32
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(resData);
32
33
  return resData;
33
34
  })
34
35
  .catch((e) => {
@@ -67,10 +67,10 @@ export class InfiniteQuery extends QueryContainer {
67
67
  this.offset += this.incrementCount;
68
68
  // запускаем запрос с последними параметрами, и флагом необходимости инкремента
69
69
  this.auxiliary
70
- .getUnifiedPromise(this.infiniteExecutor)
71
- .then((resData) => {
70
+ .getUnifiedPromise(this.infiniteExecutor, (resData) => {
72
71
  this.submitSuccess(resData, undefined, true);
73
- });
72
+ })
73
+ .catch((e) => { var _a; return (_a = this.defaultOnError) === null || _a === void 0 ? void 0 : _a.call(this, e); });
74
74
  }
75
75
  };
76
76
  /**
@@ -89,8 +89,7 @@ export class InfiniteQuery extends QueryContainer {
89
89
  this.offset = 0;
90
90
  this.isEndReached = false;
91
91
  this.auxiliary
92
- .getUnifiedPromise(this.infiniteExecutor)
93
- .then((resData) => {
92
+ .getUnifiedPromise(this.infiniteExecutor, (resData) => {
94
93
  this.submitSuccess(resData, onSuccess);
95
94
  })
96
95
  .catch((e) => {
@@ -115,16 +114,7 @@ export class InfiniteQuery extends QueryContainer {
115
114
  }
116
115
  this.offset = 0;
117
116
  this.isEndReached = false;
118
- return this.auxiliary
119
- .getUnifiedPromise(this.infiniteExecutor)
120
- .then((resData) => {
121
- this.submitSuccess(resData);
122
- return resData;
123
- })
124
- .catch((e) => {
125
- this.auxiliary.submitError(e);
126
- throw e;
127
- });
117
+ return this.auxiliary.getUnifiedPromise(this.infiniteExecutor, this.submitSuccess);
128
118
  };
129
119
  this.storage = dataStorage;
130
120
  this.incrementCount = incrementCount;
@@ -4,10 +4,6 @@ import { Mutation, } from '../Mutation';
4
4
  import { DataStorageFactory } from '../DataStorage';
5
5
  import { StatusStorageFactory } from '../StatusStorage';
6
6
  import { AdaptableMap } from '../AdaptableMap';
7
- /**
8
- * Время, спустя которое, запись о query c network-only будет удалена
9
- */
10
- const DEFAULT_TIME_TO_CLEAN = 100;
11
7
  /**
12
8
  * Сервис, позволяющий кэшировать данные.
13
9
  */
@@ -35,7 +31,7 @@ export class MobxQuery {
35
31
  * предполагается использование из домена
36
32
  */
37
33
  this.invalidate = (keysParts) => {
38
- // Сет сериализовонных ключей
34
+ // Сет сериализованных ключей
39
35
  const keysSet = new Set(keysParts.map(this.serialize));
40
36
  [...this.keys.keys()].forEach((keyHash) => {
41
37
  const key = this.keys.get(keyHash);
@@ -91,30 +87,36 @@ export class MobxQuery {
91
87
  dataStorage: this.queryDataStorageFactory.getStorage(keys.dataKeyHash),
92
88
  statusStorage: this.statusStorageFactory.getStorage(keys.statusKeyHash),
93
89
  backgroundStatusStorage: this.getBackgroundStatusStorage(keys.backgroundStatusKeyHash, Boolean(createParams === null || createParams === void 0 ? void 0 : createParams.isBackground)),
94
- submitValidity: () => this.submitValidity(keys.queryKeyHash),
90
+ submitValidity:
91
+ // 'network-only' квери не будут подтверждать свою валидность,
92
+ // следовательно, они всегда будут храниться как "слабые",
93
+ // что позволит сборщику мусора удалять их из памяти при отсутствии ссылок
94
+ fetchPolicy !== 'network-only'
95
+ ? () => this.submitValidity(keys.queryKeyHash)
96
+ : undefined,
95
97
  });
96
98
  this.queriesMap.set(keys.queryKeyHash, query);
97
99
  this.keys.set(keys.queryKeyHash, keys.queryKey);
98
- // Ожидается, что network-only квери не должны кешироваться,
99
- // но, с введением StrictMode в реакт 18, проявилась проблема,
100
- // что network-only квери, созданные в одном реакт компоненте,
101
- // создаются дважды (т.к. все хуки вызываются дважды)
102
- // и т.к. мы не ограничиваем момент запроса,
103
- // то можем получить эффект, что оба network-only квери
104
- // делают по отдельному запросу к данным единомоментно,
105
- if (fetchPolicy === 'network-only') {
106
- setTimeout(() => {
107
- this.queriesMap.delete(keys.queryKeyHash);
108
- this.keys.delete(keys.queryKeyHash);
109
- }, DEFAULT_TIME_TO_CLEAN);
110
- }
111
100
  return query;
112
101
  };
113
102
  /**
114
103
  * Метод для создания ключей к внутренним хранилищам
115
104
  */
116
105
  this.makeKeys = (rootKey, fetchPolicy, isBackground, type) => {
117
- const queryKey = [...rootKey, { fetchPolicy, isBackground, type }];
106
+ // C введением StrictMode в реакт 18, проявилась проблема,
107
+ // что network-only квери, созданные в одном реакт компоненте,
108
+ // создаются дважды (т.к. все хуки вызываются дважды)
109
+ // и т.к. мы не ограничиваем момент запроса,
110
+ // то можем получить эффект, что оба network-only квери
111
+ // делают по отдельному запросу к данным единомоментно.
112
+ // Для решения этой проблемы, добавляем уникальный ключ даты, с обнуляемыми милисекундами,
113
+ // что позволит создавать одинаковые network-only квери в течении одной секунды.
114
+ // Остается крайне редкий корнер кейс, когда разница между созданиями квери крайне мала,
115
+ // но все таки первый был создан в одной секунде, а последующее создание уже попало в следующую секунду.
116
+ // Этот кейс крайне маловероятен, и будет проявляться только в дев режиме с включенным StrictMode,
117
+ // поэтому мы пренебрегаем решением этой проблемы, в угоду упрощения.
118
+ const date = fetchPolicy === 'network-only' ? new Date().setMilliseconds(0) : null;
119
+ const queryKey = [...rootKey, { fetchPolicy, date, isBackground, type }];
118
120
  const queryKeyHash = this.serialize(queryKey);
119
121
  const dataKeyHash = this.serialize([...rootKey, { type }]);
120
122
  const statusKeyHash = this.serialize([...rootKey, { type }]);
@@ -17,8 +17,7 @@ export class Mutation extends QueryContainer {
17
17
  this.sync = (options) => {
18
18
  const { onSuccess, onError, params } = options || {};
19
19
  this.auxiliary
20
- .getUnifiedPromise(() => this.executor(params))
21
- .then((resData) => {
20
+ .getUnifiedPromise(() => this.executor(params), (resData) => {
22
21
  onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(resData);
23
22
  })
24
23
  .catch((e) => {
package/Query/Query.js CHANGED
@@ -47,8 +47,7 @@ export class Query extends QueryContainer {
47
47
  this.proceedSync = (options) => {
48
48
  const { onSuccess, onError } = options || {};
49
49
  this.auxiliary
50
- .getUnifiedPromise(this.executor)
51
- .then((res) => {
50
+ .getUnifiedPromise(this.executor, (res) => {
52
51
  this.submitSuccess(res);
53
52
  onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(res);
54
53
  })
@@ -70,9 +69,7 @@ export class Query extends QueryContainer {
70
69
  if (!this.isNetworkOnly && this.isSuccess && !this.auxiliary.isInvalid) {
71
70
  return Promise.resolve(this.storage.data);
72
71
  }
73
- return this.auxiliary
74
- .getUnifiedPromise(this.executor)
75
- .then(this.submitSuccess);
72
+ return this.auxiliary.getUnifiedPromise(this.executor, this.submitSuccess);
76
73
  };
77
74
  this.defaultOnError = onError;
78
75
  this.enabledAutoFetch = enabledAutoFetch;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astral/mobx-query",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "browser": "./index.js",
5
5
  "main": "./index.js",
6
6
  "dependencies": {