@itd-api/cache 0.1.0 → 0.3.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/README.md +22 -14
- package/dist/index.cjs +102 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -54
- package/dist/index.d.ts +103 -54
- package/dist/index.js +100 -52
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -12,8 +12,7 @@ TTL/LRU-кэш и дедупликация одновременных запро
|
|
|
12
12
|
npm install itd-api @itd-api/cache
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
`RequestOptions.extensions` и стабильный `operationId` запроса.
|
|
15
|
+
Требуется `itd-api >=0.9.0 <1.0.0`.
|
|
17
16
|
|
|
18
17
|
## Быстрый старт
|
|
19
18
|
|
|
@@ -33,13 +32,17 @@ const first = await itd.posts.get(postId); // запрос к API
|
|
|
33
32
|
const second = await itd.posts.get(postId); // ответ из кэша
|
|
34
33
|
```
|
|
35
34
|
|
|
35
|
+
Операции подключаемых модулей тоже можно кэшировать. Например, модуль Pixel Battle задаёт
|
|
36
|
+
`CachePolicyKind.Query` в `annotations.cache`, а пользователь добавляет полный `operationId`
|
|
37
|
+
в `operations`.
|
|
38
|
+
|
|
36
39
|
Кэшируются только перечисленные операции. Query, path и body входят в ключ, поэтому
|
|
37
40
|
разные страницы ленты, профили и наборы идентификаторов хранятся отдельно. Одинаковые
|
|
38
41
|
запросы, запущенные одновременно, выполняют один сетевой вызов.
|
|
39
42
|
|
|
40
|
-
Имена в `operations` —
|
|
41
|
-
правила кэша. Низкоуровневый `itd.request()` без явного
|
|
42
|
-
совпадение
|
|
43
|
+
Имена в `operations` — постоянные `operationId`, а не HTTP-пути. Изменение маршрута не ломает
|
|
44
|
+
правила кэша. Низкоуровневый `itd.request()` без явного идентификатора операции считается
|
|
45
|
+
операцией `raw`; совпадение URL со встроенным ресурсом не включает кэш автоматически.
|
|
43
46
|
|
|
44
47
|
## Настройки
|
|
45
48
|
|
|
@@ -100,11 +103,11 @@ cached.clear();
|
|
|
100
103
|
`clear()` очищает всё хранилище. Оба метода защищены от гонки: запрос, начатый до очистки,
|
|
101
104
|
не запишет устаревший результат после неё.
|
|
102
105
|
|
|
103
|
-
##
|
|
106
|
+
## События
|
|
104
107
|
|
|
105
108
|
```ts
|
|
106
|
-
const stream = itd.
|
|
107
|
-
const detachCache = cached.
|
|
109
|
+
const stream = itd.notifications.events;
|
|
110
|
+
const detachCache = cached.attachNotificationEvents(stream);
|
|
108
111
|
|
|
109
112
|
await stream.connect();
|
|
110
113
|
|
|
@@ -118,8 +121,12 @@ stream.disconnect();
|
|
|
118
121
|
пользователем, событие `unreadCount` — их счётчик. Кэш других аккаунтов и остальные операции
|
|
119
122
|
поток не изменяет.
|
|
120
123
|
|
|
121
|
-
|
|
122
|
-
|
|
124
|
+
Инвалидация подключается как промежуточный обработчик. Вызывайте
|
|
125
|
+
`attachNotificationEvents()` до прикладных обработчиков, которые могут не вызвать `next()`:
|
|
126
|
+
тогда отфильтрованное для интерфейса обновление всё равно не оставит устаревший кэш.
|
|
127
|
+
|
|
128
|
+
У стороннего событийного объекта без доступных идентификатора пользователя и базового URL
|
|
129
|
+
операции уведомлений инвалидируются во всех аккаунтах.
|
|
123
130
|
|
|
124
131
|
## Несколько клиентов
|
|
125
132
|
|
|
@@ -151,7 +158,7 @@ clientB.use(shared);
|
|
|
151
158
|
копиями не объединяет.
|
|
152
159
|
|
|
153
160
|
`maxEntries` ограничивает весь экземпляр `shared`, а `clear()` и `invalidate()` управляют
|
|
154
|
-
всеми его разделами. `
|
|
161
|
+
всеми его разделами. `attachNotificationEvents()` затрагивает аккаунт создавшего поток клиента.
|
|
155
162
|
Смена сессии сохраняет общий кэш, смена пользователя автоматически выбирает другой раздел.
|
|
156
163
|
|
|
157
164
|
## Ключ
|
|
@@ -161,11 +168,11 @@ clientB.use(shared);
|
|
|
161
168
|
- имя операции, HTTP-метод и path;
|
|
162
169
|
- базовый URL и идентификатор пользователя; для `auth.sessions` также идентификатор сессии;
|
|
163
170
|
- `service` или разовый `baseUrl`;
|
|
164
|
-
-
|
|
171
|
+
- параметры строки запроса и JSON-тело;
|
|
165
172
|
- режим `raw`, `skipAuth` и опции других плагинов, влияющие на ответ.
|
|
166
173
|
|
|
167
174
|
Токен и заголовки в ключ не входят. Также не учитываются `signal`, `timeout` и настройки
|
|
168
|
-
повторов.
|
|
175
|
+
повторов. Запрос с несериализуемым JSON-телом выполняется без кэширования.
|
|
169
176
|
|
|
170
177
|
Ответ хранится как независимая копия: изменение полученного объекта не меняет следующие
|
|
171
178
|
результаты.
|
|
@@ -184,7 +191,8 @@ clientB.use(shared);
|
|
|
184
191
|
| Files | `files.get` |
|
|
185
192
|
| Subscription | `subscription.status`, `subscription.methods` |
|
|
186
193
|
| Verification | `verification.status` |
|
|
187
|
-
| Platform | `platform.changelog`, `platform.announcements`, `platform.portal`, `
|
|
194
|
+
| Platform | `platform.changelog`, `platform.announcements`, `platform.portal`, `status.get` |
|
|
195
|
+
| Shop | `shop.products.list`, `shop.products.get`, `shop.delivery.countries`, `shop.delivery.cities`, `shop.delivery.points`, `shop.delivery.calculate` |
|
|
188
196
|
|
|
189
197
|
Страницы, загружаемые итераторами, используют операцию соответствующего списочного метода:
|
|
190
198
|
`posts.iterate()` — `posts.list`, `users.iterateFollowers()` — `users.followers` и так
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let itd_api = require("itd-api");
|
|
2
3
|
let lru_cache = require("lru-cache");
|
|
3
4
|
//#region src/errors.ts
|
|
4
5
|
/** Ошибка настройки или использования плагина кэша. */
|
|
@@ -210,8 +211,32 @@ const CACHE_OPERATIONS = freezeOperations([
|
|
|
210
211
|
category: "platform"
|
|
211
212
|
},
|
|
212
213
|
{
|
|
213
|
-
id: "
|
|
214
|
+
id: "status.get",
|
|
214
215
|
category: "platform"
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
id: "shop.products.list",
|
|
219
|
+
category: "shop"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
id: "shop.products.get",
|
|
223
|
+
category: "shop"
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
id: "shop.delivery.countries",
|
|
227
|
+
category: "shop"
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
id: "shop.delivery.cities",
|
|
231
|
+
category: "shop"
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
id: "shop.delivery.points",
|
|
235
|
+
category: "shop"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
id: "shop.delivery.calculate",
|
|
239
|
+
category: "shop"
|
|
215
240
|
}
|
|
216
241
|
]);
|
|
217
242
|
const OPERATIONS = new Map(CACHE_OPERATIONS.map((operation) => [operation.id, operation]));
|
|
@@ -224,6 +249,20 @@ function cacheOperation(operationId) {
|
|
|
224
249
|
return OPERATIONS.get(operationId);
|
|
225
250
|
}
|
|
226
251
|
//#endregion
|
|
252
|
+
//#region src/policy.ts
|
|
253
|
+
/** Виды политики кэша, объявляемой в метаданных операции. */
|
|
254
|
+
const CachePolicyKind = Object.freeze({
|
|
255
|
+
Query: "query",
|
|
256
|
+
Mutation: "mutation"
|
|
257
|
+
});
|
|
258
|
+
/** Области изоляции данных кэша. */
|
|
259
|
+
const CachePolicyScope = Object.freeze({
|
|
260
|
+
Account: "account",
|
|
261
|
+
Session: "session"
|
|
262
|
+
});
|
|
263
|
+
/** Способы инвалидации кэша после мутации. */
|
|
264
|
+
const CacheInvalidation = Object.freeze({ All: "all" });
|
|
265
|
+
//#endregion
|
|
227
266
|
//#region src/mutations.ts
|
|
228
267
|
const POST_CONTENT = [
|
|
229
268
|
"posts.list",
|
|
@@ -337,37 +376,37 @@ const CACHE_MUTATIONS = Object.freeze([
|
|
|
337
376
|
},
|
|
338
377
|
{
|
|
339
378
|
operationId: "auth.signUp",
|
|
340
|
-
invalidates:
|
|
379
|
+
invalidates: CacheInvalidation.All
|
|
341
380
|
},
|
|
342
381
|
{
|
|
343
382
|
operationId: "auth.signIn",
|
|
344
|
-
invalidates:
|
|
383
|
+
invalidates: CacheInvalidation.All
|
|
345
384
|
},
|
|
346
385
|
{
|
|
347
386
|
operationId: "auth.verifyOtp",
|
|
348
|
-
invalidates:
|
|
387
|
+
invalidates: CacheInvalidation.All
|
|
349
388
|
},
|
|
350
389
|
{
|
|
351
390
|
operationId: "auth.logout",
|
|
352
|
-
invalidates:
|
|
391
|
+
invalidates: CacheInvalidation.All
|
|
353
392
|
},
|
|
354
393
|
{
|
|
355
394
|
operationId: "auth.resetPassword",
|
|
356
|
-
invalidates:
|
|
395
|
+
invalidates: CacheInvalidation.All
|
|
357
396
|
},
|
|
358
397
|
{
|
|
359
398
|
operationId: "auth.changePassword",
|
|
360
|
-
invalidates:
|
|
399
|
+
invalidates: CacheInvalidation.All
|
|
361
400
|
},
|
|
362
401
|
{
|
|
363
402
|
operationId: "auth.revokeSession",
|
|
364
403
|
invalidates: ["auth.sessions"],
|
|
365
|
-
scope:
|
|
404
|
+
scope: CachePolicyScope.Account
|
|
366
405
|
},
|
|
367
406
|
{
|
|
368
407
|
operationId: "auth.revokeOtherSessions",
|
|
369
408
|
invalidates: ["auth.sessions"],
|
|
370
|
-
scope:
|
|
409
|
+
scope: CachePolicyScope.Account
|
|
371
410
|
},
|
|
372
411
|
{
|
|
373
412
|
operationId: "posts.create",
|
|
@@ -492,22 +531,22 @@ const CACHE_MUTATIONS = Object.freeze([
|
|
|
492
531
|
{
|
|
493
532
|
operationId: "notifications.markRead",
|
|
494
533
|
invalidates: NOTIFICATIONS,
|
|
495
|
-
scope:
|
|
534
|
+
scope: CachePolicyScope.Account
|
|
496
535
|
},
|
|
497
536
|
{
|
|
498
537
|
operationId: "notifications.markReadBatch",
|
|
499
538
|
invalidates: NOTIFICATIONS,
|
|
500
|
-
scope:
|
|
539
|
+
scope: CachePolicyScope.Account
|
|
501
540
|
},
|
|
502
541
|
{
|
|
503
542
|
operationId: "notifications.markAllRead",
|
|
504
543
|
invalidates: NOTIFICATIONS,
|
|
505
|
-
scope:
|
|
544
|
+
scope: CachePolicyScope.Account
|
|
506
545
|
},
|
|
507
546
|
{
|
|
508
547
|
operationId: "notifications.updateSettings",
|
|
509
548
|
invalidates: ["notifications.getSettings"],
|
|
510
|
-
scope:
|
|
549
|
+
scope: CachePolicyScope.Account
|
|
511
550
|
},
|
|
512
551
|
{
|
|
513
552
|
operationId: "files.upload",
|
|
@@ -520,32 +559,32 @@ const CACHE_MUTATIONS = Object.freeze([
|
|
|
520
559
|
{
|
|
521
560
|
operationId: "verification.submit",
|
|
522
561
|
invalidates: ["verification.status"],
|
|
523
|
-
scope:
|
|
562
|
+
scope: CachePolicyScope.Account
|
|
524
563
|
},
|
|
525
564
|
{
|
|
526
565
|
operationId: "subscription.pay",
|
|
527
566
|
invalidates: SUBSCRIPTION,
|
|
528
|
-
scope:
|
|
567
|
+
scope: CachePolicyScope.Account
|
|
529
568
|
},
|
|
530
569
|
{
|
|
531
570
|
operationId: "subscription.setAutoRenewal",
|
|
532
571
|
invalidates: SUBSCRIPTION,
|
|
533
|
-
scope:
|
|
572
|
+
scope: CachePolicyScope.Account
|
|
534
573
|
},
|
|
535
574
|
{
|
|
536
575
|
operationId: "subscription.bindCard",
|
|
537
576
|
invalidates: SUBSCRIPTION,
|
|
538
|
-
scope:
|
|
577
|
+
scope: CachePolicyScope.Account
|
|
539
578
|
},
|
|
540
579
|
{
|
|
541
580
|
operationId: "subscription.setDefaultMethod",
|
|
542
581
|
invalidates: SUBSCRIPTION,
|
|
543
|
-
scope:
|
|
582
|
+
scope: CachePolicyScope.Account
|
|
544
583
|
},
|
|
545
584
|
{
|
|
546
585
|
operationId: "subscription.removeMethod",
|
|
547
586
|
invalidates: SUBSCRIPTION,
|
|
548
|
-
scope:
|
|
587
|
+
scope: CachePolicyScope.Account
|
|
549
588
|
},
|
|
550
589
|
{
|
|
551
590
|
operationId: "reports.create",
|
|
@@ -591,7 +630,7 @@ function resolveOptions(options) {
|
|
|
591
630
|
if (!Array.isArray(options.operations) || options.operations.length === 0) throw new CacheError("cache.operations должен содержать хотя бы одну операцию");
|
|
592
631
|
const operations = /* @__PURE__ */ new Set();
|
|
593
632
|
for (const operation of options.operations) {
|
|
594
|
-
if (typeof operation !== "string" || !isCacheOperationId(operation)) throw new CacheError(`Неизвестная операция кэша: ${JSON.stringify(operation)}`);
|
|
633
|
+
if (typeof operation !== "string" || (0, itd_api.isBuiltInOperationId)(operation) && !isCacheOperationId(operation)) throw new CacheError(`Неизвестная операция кэша: ${JSON.stringify(operation)}`);
|
|
595
634
|
operations.add(operation);
|
|
596
635
|
}
|
|
597
636
|
const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
@@ -623,7 +662,7 @@ function cacheMode(request) {
|
|
|
623
662
|
if (!CACHE_MODES.has(mode)) throw new CacheError(`cache должен быть '${CacheModes.Default}', '${CacheModes.Reload}' или '${CacheModes.NoStore}', получено: ${String(mode)}`);
|
|
624
663
|
return mode;
|
|
625
664
|
}
|
|
626
|
-
/** Создаёт TTL/LRU-кэш
|
|
665
|
+
/** Создаёт TTL/LRU-кэш нормализованных результатов itd-api. */
|
|
627
666
|
function cache(options) {
|
|
628
667
|
const config = resolveOptions(options);
|
|
629
668
|
const values = new lru_cache.LRUCache({
|
|
@@ -649,9 +688,10 @@ function cache(options) {
|
|
|
649
688
|
if (operations.length === 0) return;
|
|
650
689
|
const selected = /* @__PURE__ */ new Set();
|
|
651
690
|
for (const operation of operations) {
|
|
652
|
-
if (
|
|
653
|
-
|
|
654
|
-
|
|
691
|
+
if (typeof operation !== "string") throw new CacheError(`Неизвестная операция кэша: ${JSON.stringify(operation)}`);
|
|
692
|
+
const operationId = operation;
|
|
693
|
+
selected.add(operationId);
|
|
694
|
+
operationGenerations.set(operationId, (operationGenerations.get(operationId) ?? 0) + 1);
|
|
655
695
|
}
|
|
656
696
|
for (const [key, entry] of values.entries()) if (selected.has(entry.operation)) values.delete(key);
|
|
657
697
|
for (const [key, entry] of pending) if (selected.has(entry.operation)) pending.delete(key);
|
|
@@ -672,11 +712,24 @@ function cache(options) {
|
|
|
672
712
|
for (const [key, entry] of pending) if (entry.accountScope === accountScope && selected.has(entry.operation)) pending.delete(key);
|
|
673
713
|
};
|
|
674
714
|
const applyMutation = (accountScope, mutation) => {
|
|
675
|
-
if (mutation.invalidates ===
|
|
676
|
-
else if (mutation.scope ===
|
|
715
|
+
if (mutation.invalidates === CacheInvalidation.All) clearScope(accountScope);
|
|
716
|
+
else if (mutation.scope === CachePolicyScope.Account) invalidateScope(accountScope, mutation.invalidates);
|
|
677
717
|
else invalidate(...mutation.invalidates);
|
|
678
718
|
};
|
|
679
|
-
const
|
|
719
|
+
const invalidateNotificationStream = (stream, ...operations) => {
|
|
720
|
+
const identity = stream.getAuthIdentity();
|
|
721
|
+
const streamBaseUrl = stream.baseUrl;
|
|
722
|
+
const legacyScope = stream.getAuthScope();
|
|
723
|
+
const accountScope = identity?.userId ? JSON.stringify([streamBaseUrl, identity.userId]) : legacyScope !== void 0 ? JSON.stringify([streamBaseUrl, legacyScope]) : void 0;
|
|
724
|
+
if (accountScope === void 0) invalidate(...operations);
|
|
725
|
+
else invalidateScope(accountScope, operations);
|
|
726
|
+
};
|
|
727
|
+
const notificationMiddleware = async (context, next) => {
|
|
728
|
+
if (context.update.type === itd_api.NotificationUpdateType.Notification) invalidateNotificationStream(context.stream, "notifications.list", "notifications.count");
|
|
729
|
+
else if (context.update.type === itd_api.NotificationUpdateType.UnreadCount) invalidateNotificationStream(context.stream, "notifications.count");
|
|
730
|
+
await next();
|
|
731
|
+
};
|
|
732
|
+
const createTransformer = (installation, baseUrl, getAuthIdentity, getAuthScope, getOperation) => {
|
|
680
733
|
const fallbackAuthScope = JSON.stringify([baseUrl, `installation:${installation}`]);
|
|
681
734
|
const resolveIdentity = async () => {
|
|
682
735
|
const identity = await getAuthIdentity?.();
|
|
@@ -691,16 +744,24 @@ function cache(options) {
|
|
|
691
744
|
};
|
|
692
745
|
};
|
|
693
746
|
return async (request, next) => {
|
|
694
|
-
const
|
|
747
|
+
const policy = getOperation(request.operationId)?.annotations?.cache;
|
|
748
|
+
const operation = cacheOperation(request.operationId) ?? (policy?.kind === CachePolicyKind.Query ? {
|
|
749
|
+
id: request.operationId,
|
|
750
|
+
category: request.operationId.split(".", 1)[0] ?? "feature"
|
|
751
|
+
} : void 0);
|
|
695
752
|
const method = request.method.toUpperCase();
|
|
696
|
-
if (!(operation !== void 0 || method === "GET" || method === "HEAD")) {
|
|
697
|
-
const mutation = cacheMutation(request.operationId)
|
|
753
|
+
if (!(policy !== void 0 ? policy.kind === CachePolicyKind.Query : operation !== void 0 || method === "GET" || method === "HEAD")) {
|
|
754
|
+
const mutation = cacheMutation(request.operationId) ?? (policy?.kind === CachePolicyKind.Mutation ? {
|
|
755
|
+
operationId: request.operationId,
|
|
756
|
+
invalidates: policy.invalidates,
|
|
757
|
+
...policy.scope === void 0 ? {} : { scope: policy.scope }
|
|
758
|
+
} : void 0);
|
|
698
759
|
const startedIdentity = mutation ? await resolveIdentity() : void 0;
|
|
699
760
|
const result = await next(request);
|
|
700
761
|
if (mutation && startedIdentity) {
|
|
701
762
|
applyMutation(startedIdentity.accountScope, mutation);
|
|
702
763
|
const currentIdentity = await resolveIdentity();
|
|
703
|
-
if (currentIdentity.accountScope !== startedIdentity.accountScope && (mutation.invalidates ===
|
|
764
|
+
if (currentIdentity.accountScope !== startedIdentity.accountScope && (mutation.invalidates === CacheInvalidation.All || mutation.scope === CachePolicyScope.Account)) applyMutation(currentIdentity.accountScope, mutation);
|
|
704
765
|
} else clear();
|
|
705
766
|
return result;
|
|
706
767
|
}
|
|
@@ -710,7 +771,7 @@ function cache(options) {
|
|
|
710
771
|
const unscopedKey = buildCacheKey(operation.id, request);
|
|
711
772
|
if (unscopedKey === void 0) return next(request);
|
|
712
773
|
const identity = await resolveIdentity();
|
|
713
|
-
const scope = operation.id === "auth.sessions" ? identity.sessionScope : identity.accountScope;
|
|
774
|
+
const scope = operation.id === "auth.sessions" || policy?.kind === CachePolicyKind.Query && policy.scope === CachePolicyScope.Session ? identity.sessionScope : identity.accountScope;
|
|
714
775
|
const key = JSON.stringify([scope, unscopedKey]);
|
|
715
776
|
if (mode === CacheModes.Reload) {
|
|
716
777
|
const state = keyStates.get(key) ?? {
|
|
@@ -749,7 +810,7 @@ function cache(options) {
|
|
|
749
810
|
const result = await next(request);
|
|
750
811
|
const stored = cloneValue(result);
|
|
751
812
|
const currentIdentity = await resolveIdentity();
|
|
752
|
-
const currentScope = operation.id === "auth.sessions" ? currentIdentity.sessionScope : currentIdentity.accountScope;
|
|
813
|
+
const currentScope = operation.id === "auth.sessions" || policy?.kind === CachePolicyKind.Query && policy.scope === CachePolicyScope.Session ? currentIdentity.sessionScope : currentIdentity.accountScope;
|
|
753
814
|
if (stored.cacheable && currentScope === scope && generation === startedGeneration && (scopeGenerations.get(identity.accountScope) ?? 0) === startedScopeGeneration && (operationGenerations.get(operation.id) ?? 0) === startedOperationGeneration && (scopeOperationGenerations.get(scopedOperationKey) ?? 0) === startedScopeOperationGeneration && keyState.generation === startedKeyGeneration) values.set(key, {
|
|
754
815
|
accountScope: identity.accountScope,
|
|
755
816
|
operation: operation.id,
|
|
@@ -786,34 +847,24 @@ function cache(options) {
|
|
|
786
847
|
},
|
|
787
848
|
clear,
|
|
788
849
|
invalidate,
|
|
789
|
-
|
|
790
|
-
if (!stream || typeof stream.
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
const streamBaseUrl = typeof stream.baseUrl === "string" && stream.baseUrl.length > 0 ? stream.baseUrl : void 0;
|
|
794
|
-
const legacyScope = typeof stream.getAuthScope === "function" ? stream.getAuthScope() : void 0;
|
|
795
|
-
const accountScope = identity?.userId && streamBaseUrl ? JSON.stringify([streamBaseUrl, identity.userId]) : legacyScope !== void 0 && streamBaseUrl ? JSON.stringify([streamBaseUrl, legacyScope]) : void 0;
|
|
796
|
-
if (accountScope === void 0) invalidate(...operations);
|
|
797
|
-
else invalidateScope(accountScope, operations);
|
|
798
|
-
};
|
|
799
|
-
invalidateStream("notifications.list", "notifications.count");
|
|
800
|
-
const offNotification = stream.on("notification", () => invalidateStream("notifications.list", "notifications.count"));
|
|
801
|
-
const offUnreadCount = stream.on("unreadCount", () => invalidateStream("notifications.count"));
|
|
802
|
-
return () => {
|
|
803
|
-
offNotification();
|
|
804
|
-
offUnreadCount();
|
|
805
|
-
};
|
|
850
|
+
attachNotificationEvents(stream) {
|
|
851
|
+
if (!stream || typeof stream.use !== "function" || typeof stream.getAuthIdentity !== "function" || typeof stream.getAuthScope !== "function" || typeof stream.baseUrl !== "string") throw new CacheError("attachNotificationEvents() принимает канал itd.notifications.events");
|
|
852
|
+
invalidateNotificationStream(stream, "notifications.list", "notifications.count");
|
|
853
|
+
return stream.use(notificationMiddleware);
|
|
806
854
|
},
|
|
807
855
|
install({ operations, baseUrl, getAuthIdentity, getAuthScope }) {
|
|
808
856
|
installationSequence += 1;
|
|
809
|
-
operations.use(createTransformer(installationSequence, baseUrl, getAuthIdentity, getAuthScope));
|
|
857
|
+
operations.use(createTransformer(installationSequence, baseUrl, getAuthIdentity, getAuthScope, operations.get));
|
|
810
858
|
}
|
|
811
859
|
};
|
|
812
860
|
}
|
|
813
861
|
//#endregion
|
|
814
862
|
exports.CACHE_OPERATIONS = CACHE_OPERATIONS;
|
|
815
863
|
exports.CacheError = CacheError;
|
|
864
|
+
exports.CacheInvalidation = CacheInvalidation;
|
|
816
865
|
exports.CacheModes = CacheModes;
|
|
866
|
+
exports.CachePolicyKind = CachePolicyKind;
|
|
867
|
+
exports.CachePolicyScope = CachePolicyScope;
|
|
817
868
|
exports.buildCacheKey = buildCacheKey;
|
|
818
869
|
exports.cache = cache;
|
|
819
870
|
exports.cacheOperation = cacheOperation;
|