@astral/mobx-query 1.15.0 → 1.16.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/MobxQuery/MobxQuery.d.ts +13 -8
- package/MobxQuery/MobxQuery.js +19 -18
- package/MobxQuery/types.d.ts +22 -0
- package/MobxQuery/types.js +1 -0
- package/PollingService/PollingService.d.ts +34 -0
- package/PollingService/PollingService.js +95 -0
- package/PollingService/index.d.ts +1 -0
- package/PollingService/index.js +1 -0
- package/README.md +22 -0
- package/SynchronizationService/SynchronizationService.d.ts +5 -5
- package/SynchronizationService/SynchronizationService.js +4 -7
- package/__test/BroadcastChannel/BroadcastChannel.d.ts +1 -0
- package/__test/BroadcastChannel/BroadcastChannel.js +13 -0
- package/__test/BroadcastChannel/index.d.ts +1 -0
- package/__test/BroadcastChannel/index.js +1 -0
- package/__test/documentMock/documentMock.d.ts +380 -0
- package/__test/documentMock/documentMock.js +18 -0
- package/__test/documentMock/index.d.ts +1 -0
- package/__test/documentMock/index.js +1 -0
- package/__test/index.d.ts +2 -0
- package/__test/index.js +2 -0
- package/node/MobxQuery/MobxQuery.d.ts +13 -8
- package/node/MobxQuery/MobxQuery.js +19 -18
- package/node/MobxQuery/types.d.ts +22 -0
- package/node/MobxQuery/types.js +2 -0
- package/node/PollingService/PollingService.d.ts +34 -0
- package/node/PollingService/PollingService.js +99 -0
- package/node/PollingService/index.d.ts +1 -0
- package/node/PollingService/index.js +17 -0
- package/node/SynchronizationService/SynchronizationService.d.ts +5 -5
- package/node/SynchronizationService/SynchronizationService.js +4 -7
- package/node/__test/BroadcastChannel/BroadcastChannel.d.ts +1 -0
- package/node/__test/BroadcastChannel/BroadcastChannel.js +17 -0
- package/node/__test/BroadcastChannel/index.d.ts +1 -0
- package/node/__test/BroadcastChannel/index.js +17 -0
- package/node/__test/documentMock/documentMock.d.ts +380 -0
- package/node/__test/documentMock/documentMock.js +22 -0
- package/node/__test/documentMock/index.d.ts +1 -0
- package/node/__test/documentMock/index.js +17 -0
- package/node/__test/index.d.ts +2 -0
- package/node/__test/index.js +18 -0
- package/package.json +4 -2
package/MobxQuery/MobxQuery.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Mutation, type MutationExecutor, type MutationParams } from '../Mutatio
|
|
|
3
3
|
import { Query, type QueryExecutor, type QueryParams } from '../Query';
|
|
4
4
|
import { InfiniteQuerySet, type InfiniteQuerySetConfig, type InfiniteQuerySetConfigurator, MutationSet, QuerySet, type QuerySetConfig, type QuerySetConfigurator } from '../Sets';
|
|
5
5
|
import type { CacheKey, FetchPolicy } from '../types';
|
|
6
|
+
import type { UnknownCachedQuery } from './types';
|
|
6
7
|
/**
|
|
7
8
|
* Стандартный обработчик ошибки запроса,
|
|
8
9
|
* будет вызван, если при вызове sync не был передан отдельный onError параметр
|
|
@@ -15,6 +16,12 @@ type WithSynchronization = {
|
|
|
15
16
|
*/
|
|
16
17
|
enabledSynchronization?: boolean;
|
|
17
18
|
};
|
|
19
|
+
type WithPollingTime = {
|
|
20
|
+
/**
|
|
21
|
+
* Время в мс, раз в которое необходимо инвалидировать query
|
|
22
|
+
*/
|
|
23
|
+
pollingTime?: number;
|
|
24
|
+
};
|
|
18
25
|
type MobxQueryParams = {
|
|
19
26
|
/**
|
|
20
27
|
* Политика получения данных по умолчанию.
|
|
@@ -43,19 +50,15 @@ export type CreateQueryParams<TResult, TError, TIsBackground extends boolean> =
|
|
|
43
50
|
* @default false
|
|
44
51
|
*/
|
|
45
52
|
isBackground?: TIsBackground;
|
|
46
|
-
} & WithSynchronization;
|
|
53
|
+
} & WithSynchronization & WithPollingTime;
|
|
47
54
|
export type CreateInfiniteQueryParams<TResult, TError, TIsBackground extends boolean> = Omit<InfiniteQueryParams<TResult, TError, TIsBackground>, 'dataStorage' | 'statusStorage' | 'backgroundStatusStorage' | 'submitValidity'> & {
|
|
48
55
|
/**
|
|
49
56
|
* Режим фонового обновления
|
|
50
57
|
* @default false
|
|
51
58
|
*/
|
|
52
59
|
isBackground?: TIsBackground;
|
|
53
|
-
} & WithSynchronization;
|
|
60
|
+
} & WithSynchronization & WithPollingTime;
|
|
54
61
|
export type CreateMutationParams<TResult, TError> = MutationParams<TResult, TError>;
|
|
55
|
-
/**
|
|
56
|
-
* Внутриний тип кешируемого стора
|
|
57
|
-
*/
|
|
58
|
-
type CachedQuery<TResult, TError, TIsBackground extends boolean> = Query<TResult, TError, TIsBackground> | InfiniteQuery<TResult, TError, TIsBackground>;
|
|
59
62
|
/**
|
|
60
63
|
* Стратегия инвалидации кэша
|
|
61
64
|
* @property 'partial-match' - Проверяет наличие хотя бы одной части ключа в кэше
|
|
@@ -97,11 +100,12 @@ export declare class MobxQuery<TDefaultError = void> {
|
|
|
97
100
|
private readonly defaultEnabledAutoFetch;
|
|
98
101
|
private readonly defauleEnabledSynchronization;
|
|
99
102
|
private readonly synchronizationService;
|
|
103
|
+
private readonly pollingService;
|
|
100
104
|
private serialize;
|
|
101
105
|
constructor({ onError, fetchPolicy, enabledAutoFetch, enabledSynchronization, }?: MobxQueryParams, _BroadcastChannel?: {
|
|
102
106
|
new (name: string): BroadcastChannel;
|
|
103
107
|
prototype: BroadcastChannel;
|
|
104
|
-
});
|
|
108
|
+
}, _document?: Document);
|
|
105
109
|
/**
|
|
106
110
|
* Проверяет пересечение ключей в зависимости от стратегии
|
|
107
111
|
* @param invalidatedKeys - Ключи для инвалидации
|
|
@@ -123,6 +127,7 @@ export declare class MobxQuery<TDefaultError = void> {
|
|
|
123
127
|
* mobxQuery.invalidate(['users', '1'], 'chain-match'); // Инвалидирует только query с точным набором ключей ['users', '1']
|
|
124
128
|
*/
|
|
125
129
|
invalidate: (invalidatedKeys: CacheKey[], strategy?: InvalidateStrategy) => void;
|
|
130
|
+
private invalidateByKeyHash;
|
|
126
131
|
/**
|
|
127
132
|
* Метод для получения массива хешей ключей на основании ключей и стратегии
|
|
128
133
|
*/
|
|
@@ -130,7 +135,7 @@ export declare class MobxQuery<TDefaultError = void> {
|
|
|
130
135
|
/**
|
|
131
136
|
* метод для получения массива существующий квери на основании ключей и стратегии
|
|
132
137
|
*/
|
|
133
|
-
getExistsQueries: <TQuery =
|
|
138
|
+
getExistsQueries: <TQuery = UnknownCachedQuery>(keys: CacheKey[], strategy?: InvalidateStrategy) => TQuery[];
|
|
134
139
|
private submitValidity;
|
|
135
140
|
/**
|
|
136
141
|
* Метод инвалидации всех query
|
package/MobxQuery/MobxQuery.js
CHANGED
|
@@ -2,6 +2,7 @@ import { AdaptableMap } from '../AdaptableMap';
|
|
|
2
2
|
import { DataStorageFactory } from '../DataStorage';
|
|
3
3
|
import { InfiniteQuery, } from '../InfiniteQuery';
|
|
4
4
|
import { Mutation, } from '../Mutation';
|
|
5
|
+
import { PollingService } from '../PollingService';
|
|
5
6
|
import { Query } from '../Query';
|
|
6
7
|
import { InfiniteQuerySet, MutationSet, QuerySet, } from '../Sets';
|
|
7
8
|
import { StatusStorageFactory } from '../StatusStorage';
|
|
@@ -10,7 +11,7 @@ import { SynchronizationService } from '../SynchronizationService';
|
|
|
10
11
|
* Сервис, позволяющий кэшировать данные.
|
|
11
12
|
*/
|
|
12
13
|
export class MobxQuery {
|
|
13
|
-
constructor({ onError, fetchPolicy = 'cache-first', enabledAutoFetch = false, enabledSynchronization = false, } = {}, _BroadcastChannel = globalThis.BroadcastChannel) {
|
|
14
|
+
constructor({ onError, fetchPolicy = 'cache-first', enabledAutoFetch = false, enabledSynchronization = false, } = {}, _BroadcastChannel = globalThis.BroadcastChannel, _document = globalThis.document) {
|
|
14
15
|
/**
|
|
15
16
|
* Объект соответствия хешей ключей и их значений
|
|
16
17
|
*/
|
|
@@ -55,13 +56,15 @@ export class MobxQuery {
|
|
|
55
56
|
* mobxQuery.invalidate(['users', '1'], 'chain-match'); // Инвалидирует только query с точным набором ключей ['users', '1']
|
|
56
57
|
*/
|
|
57
58
|
this.invalidate = (invalidatedKeys, strategy = 'partial-match') => {
|
|
58
|
-
this.getExistsKeyHashes(invalidatedKeys, strategy).forEach(({ keyHash }) =>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
this.getExistsKeyHashes(invalidatedKeys, strategy).forEach(({ keyHash }) => this.invalidateByKeyHash(keyHash));
|
|
60
|
+
};
|
|
61
|
+
this.invalidateByKeyHash = (keyHash) => {
|
|
62
|
+
var _a;
|
|
63
|
+
(_a = this.queriesMap.get(keyHash)) === null || _a === void 0 ? void 0 : _a.invalidate();
|
|
64
|
+
// Конвертируем инвалидированный квери в слабый,
|
|
65
|
+
// чтобы сборщик мусора мог удалить неиспользуемые квери
|
|
66
|
+
this.queriesMap.convertToWeak(keyHash);
|
|
67
|
+
this.pollingService.clean(keyHash);
|
|
65
68
|
};
|
|
66
69
|
/**
|
|
67
70
|
* Метод для получения массива хешей ключей на основании ключей и стратегии
|
|
@@ -78,10 +81,13 @@ export class MobxQuery {
|
|
|
78
81
|
*/
|
|
79
82
|
this.getExistsQueries = (keys, strategy = 'partial-match') => this.getExistsKeyHashes(keys, strategy).map(({ keyHash }) => this.queriesMap.get(keyHash));
|
|
80
83
|
// Метод для подтверждения того, что квери успешно получил валидные данные
|
|
81
|
-
this.submitValidity = (keys, isNetworkOnly, enabledSynchronization) => {
|
|
84
|
+
this.submitValidity = (keys, isNetworkOnly, enabledSynchronization, pollingTime) => {
|
|
82
85
|
if (enabledSynchronization) {
|
|
83
86
|
this.synchronizationService.emit(keys);
|
|
84
87
|
}
|
|
88
|
+
if (pollingTime) {
|
|
89
|
+
this.pollingService.setupTimer(keys.queryKeyHash, pollingTime);
|
|
90
|
+
}
|
|
85
91
|
// 'network-only' квери не будут конвертироваться,
|
|
86
92
|
// следовательно, они всегда будут храниться как "слабые",
|
|
87
93
|
// что позволит сборщику мусора удалять их из памяти при отсутствии ссылок
|
|
@@ -95,13 +101,7 @@ export class MobxQuery {
|
|
|
95
101
|
/**
|
|
96
102
|
* Метод инвалидации всех query
|
|
97
103
|
*/
|
|
98
|
-
this.invalidateQueries = () =>
|
|
99
|
-
[...this.keys.keys()].forEach((keyHash) => {
|
|
100
|
-
var _a;
|
|
101
|
-
(_a = this.queriesMap.get(keyHash)) === null || _a === void 0 ? void 0 : _a.invalidate();
|
|
102
|
-
this.queriesMap.convertToWeak(keyHash);
|
|
103
|
-
});
|
|
104
|
-
};
|
|
104
|
+
this.invalidateQueries = () => [...this.keys.keys()].forEach(this.invalidateByKeyHash);
|
|
105
105
|
/**
|
|
106
106
|
* Метод, который занимается проверкой наличия квери по ключу,
|
|
107
107
|
* и если нет, создает новый, добавляет его к себе в память, и возвращает его пользователю
|
|
@@ -124,7 +124,7 @@ export class MobxQuery {
|
|
|
124
124
|
backgroundStatusStorage: this.getBackgroundStatusStorage(keys.backgroundStatusKeyHash, Boolean(createParams === null || createParams === void 0 ? void 0 : createParams.isBackground)),
|
|
125
125
|
submitValidity: () => {
|
|
126
126
|
var _a;
|
|
127
|
-
return this.submitValidity(keys, fetchPolicy !== 'network-only', (_a = createParams === null || createParams === void 0 ? void 0 : createParams.enabledSynchronization) !== null && _a !== void 0 ? _a : this.defauleEnabledSynchronization);
|
|
127
|
+
return this.submitValidity(keys, fetchPolicy !== 'network-only', (_a = createParams === null || createParams === void 0 ? void 0 : createParams.enabledSynchronization) !== null && _a !== void 0 ? _a : this.defauleEnabledSynchronization, createParams === null || createParams === void 0 ? void 0 : createParams.pollingTime);
|
|
128
128
|
},
|
|
129
129
|
});
|
|
130
130
|
this.queriesMap.set(keys.queryKeyHash, query);
|
|
@@ -228,6 +228,7 @@ export class MobxQuery {
|
|
|
228
228
|
this.defaultFetchPolicy = fetchPolicy;
|
|
229
229
|
this.defaultEnabledAutoFetch = enabledAutoFetch;
|
|
230
230
|
this.defauleEnabledSynchronization = enabledSynchronization;
|
|
231
|
-
this.
|
|
231
|
+
this.pollingService = new PollingService(this.queriesMap, this.invalidateByKeyHash, _document);
|
|
232
|
+
this.synchronizationService = new SynchronizationService(this.statusStorageFactory, this.queryDataStorageFactory, this.pollingService, _BroadcastChannel);
|
|
232
233
|
}
|
|
233
234
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type InfiniteQuery } from '../InfiniteQuery';
|
|
2
|
+
import { type Query } from '../Query';
|
|
3
|
+
import { type CacheKey } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Внутриний тип кешируемого стора
|
|
6
|
+
*/
|
|
7
|
+
export type CachedQuery<TResult, TError, TIsBackground extends boolean> = Query<TResult, TError, TIsBackground> | InfiniteQuery<TResult, TError, TIsBackground>;
|
|
8
|
+
export type UnknownCachedQuery = CachedQuery<unknown, unknown, false>;
|
|
9
|
+
/**
|
|
10
|
+
* Хэш ключа
|
|
11
|
+
*/
|
|
12
|
+
export type KeyHash = string;
|
|
13
|
+
/**
|
|
14
|
+
* Набор ключей
|
|
15
|
+
*/
|
|
16
|
+
export type Keys = {
|
|
17
|
+
queryKey: CacheKey[];
|
|
18
|
+
dataKeyHash: KeyHash;
|
|
19
|
+
statusKeyHash: KeyHash;
|
|
20
|
+
queryKeyHash: KeyHash;
|
|
21
|
+
backgroundStatusKeyHash: KeyHash;
|
|
22
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type AdaptableMap } from '../AdaptableMap';
|
|
2
|
+
import { type KeyHash, type UnknownCachedQuery } from '../MobxQuery/types';
|
|
3
|
+
/**
|
|
4
|
+
* Сущность для инкапсулирования логики работы с устареванием данных
|
|
5
|
+
*/
|
|
6
|
+
export declare class PollingService {
|
|
7
|
+
private readonly _queryStorage;
|
|
8
|
+
private readonly _invalidateByKeyHash;
|
|
9
|
+
private readonly _document;
|
|
10
|
+
private timers;
|
|
11
|
+
private timerDates;
|
|
12
|
+
private isVisible;
|
|
13
|
+
constructor(_queryStorage: AdaptableMap<UnknownCachedQuery>, _invalidateByKeyHash: (keyHash: KeyHash) => void, _document?: Document);
|
|
14
|
+
private updateIsVisible;
|
|
15
|
+
private init;
|
|
16
|
+
private handleVisibilityChange;
|
|
17
|
+
private restartPausedTimers;
|
|
18
|
+
private pauseTimers;
|
|
19
|
+
/**
|
|
20
|
+
* Очистка таймеров,
|
|
21
|
+
* предполагается использование либо при срабатывании таймера,
|
|
22
|
+
* либо при досрочном вызове из внешней инвалидации
|
|
23
|
+
*/
|
|
24
|
+
clean: (key: KeyHash) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Перезапуск имеющегося таймера, предполагается использование при срабатывании синхронизации между вкладками
|
|
27
|
+
*/
|
|
28
|
+
restart: (key: KeyHash) => void;
|
|
29
|
+
private invalidate;
|
|
30
|
+
/**
|
|
31
|
+
* Установка таймера устаревания данных
|
|
32
|
+
*/
|
|
33
|
+
setupTimer: (key: KeyHash, pollingTime: number) => void;
|
|
34
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Сущность для инкапсулирования логики работы с устареванием данных
|
|
3
|
+
*/
|
|
4
|
+
export class PollingService {
|
|
5
|
+
constructor(_queryStorage, _invalidateByKeyHash, _document = globalThis.document) {
|
|
6
|
+
this._queryStorage = _queryStorage;
|
|
7
|
+
this._invalidateByKeyHash = _invalidateByKeyHash;
|
|
8
|
+
this._document = _document;
|
|
9
|
+
this.timers = new Map();
|
|
10
|
+
this.timerDates = new Map();
|
|
11
|
+
this.isVisible = true;
|
|
12
|
+
this.updateIsVisible = () => {
|
|
13
|
+
var _a;
|
|
14
|
+
this.isVisible = ((_a = this._document) === null || _a === void 0 ? void 0 : _a.visibilityState) === 'visible';
|
|
15
|
+
};
|
|
16
|
+
this.init = () => {
|
|
17
|
+
var _a;
|
|
18
|
+
this.updateIsVisible();
|
|
19
|
+
(_a = this._document) === null || _a === void 0 ? void 0 : _a.addEventListener('visibilitychange', this.handleVisibilityChange);
|
|
20
|
+
};
|
|
21
|
+
this.handleVisibilityChange = () => {
|
|
22
|
+
this.updateIsVisible();
|
|
23
|
+
if (this.isVisible) {
|
|
24
|
+
this.restartPausedTimers();
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
this.pauseTimers();
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
this.restartPausedTimers = () => {
|
|
31
|
+
this.timerDates.keys().forEach((key) => {
|
|
32
|
+
const dateNow = Date.now();
|
|
33
|
+
const { pollingTime, targetDate } = this.timerDates.get(key);
|
|
34
|
+
const isAlreadyExpired = targetDate < dateNow;
|
|
35
|
+
if (isAlreadyExpired) {
|
|
36
|
+
this.invalidate(key);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.setupTimer(key, pollingTime);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
this.pauseTimers = () => {
|
|
44
|
+
this.timers.keys().forEach((key) => {
|
|
45
|
+
globalThis.clearTimeout(this.timers.get(key));
|
|
46
|
+
this.timers.delete(key);
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Очистка таймеров,
|
|
51
|
+
* предполагается использование либо при срабатывании таймера,
|
|
52
|
+
* либо при досрочном вызове из внешней инвалидации
|
|
53
|
+
*/
|
|
54
|
+
this.clean = (key) => {
|
|
55
|
+
globalThis.clearTimeout(this.timers.get(key));
|
|
56
|
+
this.timers.delete(key);
|
|
57
|
+
this.timerDates.delete(key);
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Перезапуск имеющегося таймера, предполагается использование при срабатывании синхронизации между вкладками
|
|
61
|
+
*/
|
|
62
|
+
this.restart = (key) => {
|
|
63
|
+
const saved = this.timerDates.get(key);
|
|
64
|
+
if (saved) {
|
|
65
|
+
this.setupTimer(key, saved.pollingTime);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
this.invalidate = (key) => {
|
|
69
|
+
const query = this._queryStorage.get(key);
|
|
70
|
+
if (query) {
|
|
71
|
+
this._invalidateByKeyHash(key);
|
|
72
|
+
}
|
|
73
|
+
this.clean(key);
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Установка таймера устаревания данных
|
|
77
|
+
*/
|
|
78
|
+
this.setupTimer = (key, pollingTime) => {
|
|
79
|
+
if (this.timers.has(key)) {
|
|
80
|
+
globalThis.clearTimeout(this.timers.get(key));
|
|
81
|
+
}
|
|
82
|
+
if (!this._queryStorage.get(key)) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
this.timerDates.set(key, {
|
|
86
|
+
pollingTime,
|
|
87
|
+
targetDate: Date.now() + pollingTime,
|
|
88
|
+
});
|
|
89
|
+
if (this.isVisible) {
|
|
90
|
+
this.timers.set(key, globalThis.setTimeout(() => this.invalidate(key), pollingTime));
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
this.init();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './PollingService';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './PollingService';
|
package/README.md
CHANGED
|
@@ -1098,6 +1098,28 @@ export type InfiniteQueryConfig = {
|
|
|
1098
1098
|
};
|
|
1099
1099
|
```
|
|
1100
1100
|
|
|
1101
|
+
### Переодическая инвалидация (Поллинг)
|
|
1102
|
+
|
|
1103
|
+
Для обеспечения автоматической инвалидации данных по указанному времени используйте настройку `pollingTime` при создании query.
|
|
1104
|
+
Значение необходимо указывать в милисекундах.
|
|
1105
|
+
|
|
1106
|
+
```ts
|
|
1107
|
+
const TEN_MINUTES = 10 * 60 * 1000;
|
|
1108
|
+
|
|
1109
|
+
docsfetcher.queries.document.createWithConfig(
|
|
1110
|
+
{
|
|
1111
|
+
pollingTime: TEN_MINUTES,
|
|
1112
|
+
},
|
|
1113
|
+
documenId,
|
|
1114
|
+
);
|
|
1115
|
+
|
|
1116
|
+
docsfetcher.infiniteQueries.list.createWithConfig(
|
|
1117
|
+
{
|
|
1118
|
+
pollingTime: TEN_MINUTES,
|
|
1119
|
+
},
|
|
1120
|
+
);
|
|
1121
|
+
```
|
|
1122
|
+
|
|
1101
1123
|
### Mutation
|
|
1102
1124
|
|
|
1103
1125
|
`Mutation` предназначен для отправки данных на сервер с целью произведения изменений.
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { type DataStorageFactory } from '../DataStorage';
|
|
2
|
+
import { type Keys } from '../MobxQuery/types';
|
|
3
|
+
import { type PollingService } from '../PollingService';
|
|
2
4
|
import { type StatusStorageFactory } from '../StatusStorage';
|
|
3
5
|
export declare class SynchronizationService {
|
|
4
6
|
private readonly _statusStorageFactory;
|
|
5
7
|
private readonly _dataStorageFactory;
|
|
8
|
+
private readonly _pollingService;
|
|
6
9
|
private readonly broadcastChannel?;
|
|
7
|
-
constructor(_statusStorageFactory: StatusStorageFactory, _dataStorageFactory: DataStorageFactory, _BroadcastChannel?: {
|
|
10
|
+
constructor(_statusStorageFactory: StatusStorageFactory, _dataStorageFactory: DataStorageFactory, _pollingService: PollingService, _BroadcastChannel?: {
|
|
8
11
|
new (name: string): BroadcastChannel;
|
|
9
12
|
prototype: BroadcastChannel;
|
|
10
13
|
});
|
|
11
14
|
private init;
|
|
12
|
-
emit: (keys:
|
|
13
|
-
dataKeyHash: string;
|
|
14
|
-
statusKeyHash: string;
|
|
15
|
-
}) => void;
|
|
15
|
+
emit: (keys: Keys) => void;
|
|
16
16
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export class SynchronizationService {
|
|
2
|
-
constructor(_statusStorageFactory, _dataStorageFactory, _BroadcastChannel = globalThis.BroadcastChannel) {
|
|
2
|
+
constructor(_statusStorageFactory, _dataStorageFactory, _pollingService, _BroadcastChannel = globalThis.BroadcastChannel) {
|
|
3
3
|
this._statusStorageFactory = _statusStorageFactory;
|
|
4
4
|
this._dataStorageFactory = _dataStorageFactory;
|
|
5
|
+
this._pollingService = _pollingService;
|
|
5
6
|
this.init = () => {
|
|
6
7
|
var _a;
|
|
7
8
|
(_a = this.broadcastChannel) === null || _a === void 0 ? void 0 : _a.addEventListener('message', (event) => {
|
|
@@ -10,16 +11,12 @@ export class SynchronizationService {
|
|
|
10
11
|
.getStorage(event.data.dataKeyHash)) === null || _a === void 0 ? void 0 : _a.setData(event.data.data);
|
|
11
12
|
(_b = this._statusStorageFactory
|
|
12
13
|
.getStorage(event.data.statusKeyHash)) === null || _b === void 0 ? void 0 : _b.setStatues(event.data.statuses);
|
|
14
|
+
this._pollingService.restart(event.data.queryKeyHash);
|
|
13
15
|
});
|
|
14
16
|
};
|
|
15
17
|
this.emit = (keys) => {
|
|
16
18
|
var _a, _b, _c;
|
|
17
|
-
(_a = this.broadcastChannel) === null || _a === void 0 ? void 0 : _a.postMessage({
|
|
18
|
-
dataKeyHash: keys.dataKeyHash,
|
|
19
|
-
statusKeyHash: keys.statusKeyHash,
|
|
20
|
-
data: (_b = this._dataStorageFactory.getStorage(keys.dataKeyHash)) === null || _b === void 0 ? void 0 : _b.data,
|
|
21
|
-
statuses: (_c = this._statusStorageFactory.getStorage(keys.statusKeyHash)) === null || _c === void 0 ? void 0 : _c.statuses,
|
|
22
|
-
});
|
|
19
|
+
(_a = this.broadcastChannel) === null || _a === void 0 ? void 0 : _a.postMessage(Object.assign(Object.assign({}, keys), { data: (_b = this._dataStorageFactory.getStorage(keys.dataKeyHash)) === null || _b === void 0 ? void 0 : _b.data, statuses: (_c = this._statusStorageFactory.getStorage(keys.statusKeyHash)) === null || _c === void 0 ? void 0 : _c.statuses }));
|
|
23
20
|
};
|
|
24
21
|
if (_BroadcastChannel) {
|
|
25
22
|
this.broadcastChannel = new _BroadcastChannel('@astral/mobx-query');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const createBroadcastChannelMock: () => typeof globalThis.BroadcastChannel;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Мок не предусматривает полного повторения функционала оригинального BroadcastChannelMock
|
|
2
|
+
// поэтому он будет вызывать даже подписчиков вкладки инициатора,
|
|
3
|
+
// но благодаря общему подходу, ожидается, что это не вызовет проблем
|
|
4
|
+
export const createBroadcastChannelMock = () => {
|
|
5
|
+
const listeners = [];
|
|
6
|
+
class BroadcastChannelMock {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.addEventListener = (_, listener) => listeners.push(listener);
|
|
9
|
+
this.postMessage = (data) => listeners.forEach((listener) => listener({ data }));
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return BroadcastChannelMock;
|
|
13
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './BroadcastChannel';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './BroadcastChannel';
|