@itd-api/cache 0.0.1 → 0.1.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/dist/index.d.ts CHANGED
@@ -1,271 +1,191 @@
1
- import { RawRequestOptions, ItdPlugin, ItdRealtime, Unsubscribe } from 'itd-api';
2
-
1
+ import { BuiltInOperationId, ClientPlugin, ItdRealtime, OperationId, OperationRequestOptions, RealtimeContext, Unsubscribe } from "itd-api";
2
+ //#region src/errors.d.ts
3
3
  /** Ошибка настройки или использования плагина кэша. */
4
4
  declare class CacheError extends Error {
5
- readonly name = "CacheError";
5
+ readonly name = "CacheError";
6
6
  }
7
-
8
- /** Описание читающего маршрута itd-api. */
9
- interface CacheRoute {
10
- /** Публичное имя для настройки плагина. */
11
- id: string;
12
- /** Раздел клиента. */
13
- category: string;
14
- /** HTTP-метод маршрута. */
15
- method: string;
16
- /** Путь без query и базового URL. */
17
- path: RegExp;
7
+ //#endregion
8
+ //#region src/operations.d.ts
9
+ /** Описание читающей операции itd-api. */
10
+ interface CacheOperation {
11
+ /** Стабильный ID операции и публичное имя для настройки плагина. */
12
+ id: BuiltInOperationId;
13
+ /** Раздел клиента. */
14
+ category: string;
18
15
  }
19
- /**
20
- * Читающие маршруты, которые можно кэшировать.
21
- *
22
- * Порядок значим: точные служебные пути стоят перед динамическими маршрутами.
23
- */
24
- declare const CACHE_ROUTES: readonly [{
25
- readonly id: "auth.sessions";
26
- readonly category: "auth";
27
- readonly method: "GET";
28
- readonly path: RegExp;
29
- }, {
30
- readonly id: "users.me";
31
- readonly category: "users";
32
- readonly method: "GET";
33
- readonly path: RegExp;
34
- }, {
35
- readonly id: "users.checkUsername";
36
- readonly category: "users";
37
- readonly method: "GET";
38
- readonly path: RegExp;
39
- }, {
40
- readonly id: "users.search";
41
- readonly category: "users";
42
- readonly method: "GET";
43
- readonly path: RegExp;
44
- }, {
45
- readonly id: "users.whoToFollow";
46
- readonly category: "users";
47
- readonly method: "GET";
48
- readonly path: RegExp;
49
- }, {
50
- readonly id: "users.topClans";
51
- readonly category: "users";
52
- readonly method: "GET";
53
- readonly path: RegExp;
54
- }, {
55
- readonly id: "users.followers";
56
- readonly category: "users";
57
- readonly method: "GET";
58
- readonly path: RegExp;
59
- }, {
60
- readonly id: "users.following";
61
- readonly category: "users";
62
- readonly method: "GET";
63
- readonly path: RegExp;
64
- }, {
65
- readonly id: "users.blocked";
66
- readonly category: "users";
67
- readonly method: "GET";
68
- readonly path: RegExp;
69
- }, {
70
- readonly id: "users.getPrivacy";
71
- readonly category: "users";
72
- readonly method: "GET";
73
- readonly path: RegExp;
74
- }, {
75
- readonly id: "users.pins";
76
- readonly category: "users";
77
- readonly method: "GET";
78
- readonly path: RegExp;
79
- }, {
80
- readonly id: "users.followStatus";
81
- readonly category: "users";
82
- readonly method: "POST";
83
- readonly path: RegExp;
84
- }, {
85
- readonly id: "users.get";
86
- readonly category: "users";
87
- readonly method: "GET";
88
- readonly path: RegExp;
89
- }, {
90
- readonly id: "posts.list";
91
- readonly category: "posts";
92
- readonly method: "GET";
93
- readonly path: RegExp;
94
- }, {
95
- readonly id: "posts.likedByUser";
96
- readonly category: "posts";
97
- readonly method: "GET";
98
- readonly path: RegExp;
99
- }, {
100
- readonly id: "posts.byUser";
101
- readonly category: "posts";
102
- readonly method: "GET";
103
- readonly path: RegExp;
104
- }, {
105
- readonly id: "posts.comments";
106
- readonly category: "posts";
107
- readonly method: "GET";
108
- readonly path: RegExp;
109
- }, {
110
- readonly id: "posts.stats";
111
- readonly category: "posts";
112
- readonly method: "POST";
113
- readonly path: RegExp;
114
- }, {
115
- readonly id: "posts.get";
116
- readonly category: "posts";
117
- readonly method: "GET";
118
- readonly path: RegExp;
119
- }, {
120
- readonly id: "comments.replies";
121
- readonly category: "comments";
122
- readonly method: "GET";
123
- readonly path: RegExp;
124
- }, {
125
- readonly id: "notifications.list";
126
- readonly category: "notifications";
127
- readonly method: "GET";
128
- readonly path: RegExp;
129
- }, {
130
- readonly id: "notifications.count";
131
- readonly category: "notifications";
132
- readonly method: "GET";
133
- readonly path: RegExp;
134
- }, {
135
- readonly id: "notifications.getSettings";
136
- readonly category: "notifications";
137
- readonly method: "GET";
138
- readonly path: RegExp;
139
- }, {
140
- readonly id: "hashtags.search";
141
- readonly category: "hashtags";
142
- readonly method: "GET";
143
- readonly path: RegExp;
144
- }, {
145
- readonly id: "hashtags.trending";
146
- readonly category: "hashtags";
147
- readonly method: "GET";
148
- readonly path: RegExp;
149
- }, {
150
- readonly id: "hashtags.posts";
151
- readonly category: "hashtags";
152
- readonly method: "GET";
153
- readonly path: RegExp;
154
- }, {
155
- readonly id: "search.all";
156
- readonly category: "search";
157
- readonly method: "GET";
158
- readonly path: RegExp;
159
- }, {
160
- readonly id: "files.get";
161
- readonly category: "files";
162
- readonly method: "GET";
163
- readonly path: RegExp;
164
- }, {
165
- readonly id: "subscription.status";
166
- readonly category: "subscription";
167
- readonly method: "GET";
168
- readonly path: RegExp;
169
- }, {
170
- readonly id: "subscription.methods";
171
- readonly category: "subscription";
172
- readonly method: "GET";
173
- readonly path: RegExp;
174
- }, {
175
- readonly id: "verification.status";
176
- readonly category: "verification";
177
- readonly method: "GET";
178
- readonly path: RegExp;
179
- }, {
180
- readonly id: "platform.changelog";
181
- readonly category: "platform";
182
- readonly method: "GET";
183
- readonly path: RegExp;
184
- }, {
185
- readonly id: "platform.announcements";
186
- readonly category: "platform";
187
- readonly method: "GET";
188
- readonly path: RegExp;
189
- }, {
190
- readonly id: "platform.portal";
191
- readonly category: "platform";
192
- readonly method: "GET";
193
- readonly path: RegExp;
194
- }, {
195
- readonly id: "platform.status";
196
- readonly category: "platform";
197
- readonly method: "GET";
198
- readonly path: RegExp;
199
- }];
200
- /** Имя маршрута, доступное в `cache({ routes: … })`. */
201
- type CacheRouteId = (typeof CACHE_ROUTES)[number]['id'];
202
- /** Раздел маршрута. */
203
- type CacheRouteCategory = (typeof CACHE_ROUTES)[number]['category'];
204
- /** Проверяет публичное имя маршрута. */
205
- declare function isCacheRouteId(value: string): value is CacheRouteId;
206
- /** Находит читающий маршрут по HTTP-методу и пути. */
207
- declare function cacheRoute(method: string, path: string): (typeof CACHE_ROUTES)[number] | undefined;
208
-
16
+ /** Читающие операции, которые можно кэшировать. */
17
+ declare const CACHE_OPERATIONS: readonly [Readonly<{
18
+ readonly id: "auth.sessions";
19
+ readonly category: "auth";
20
+ }>, Readonly<{
21
+ readonly id: "users.me";
22
+ readonly category: "users";
23
+ }>, Readonly<{
24
+ readonly id: "users.checkUsername";
25
+ readonly category: "users";
26
+ }>, Readonly<{
27
+ readonly id: "users.search";
28
+ readonly category: "users";
29
+ }>, Readonly<{
30
+ readonly id: "users.whoToFollow";
31
+ readonly category: "users";
32
+ }>, Readonly<{
33
+ readonly id: "users.topClans";
34
+ readonly category: "users";
35
+ }>, Readonly<{
36
+ readonly id: "users.followers";
37
+ readonly category: "users";
38
+ }>, Readonly<{
39
+ readonly id: "users.following";
40
+ readonly category: "users";
41
+ }>, Readonly<{
42
+ readonly id: "users.blocked";
43
+ readonly category: "users";
44
+ }>, Readonly<{
45
+ readonly id: "users.getPrivacy";
46
+ readonly category: "users";
47
+ }>, Readonly<{
48
+ readonly id: "users.pins";
49
+ readonly category: "users";
50
+ }>, Readonly<{
51
+ readonly id: "users.followStatus";
52
+ readonly category: "users";
53
+ }>, Readonly<{
54
+ readonly id: "users.get";
55
+ readonly category: "users";
56
+ }>, Readonly<{
57
+ readonly id: "posts.list";
58
+ readonly category: "posts";
59
+ }>, Readonly<{
60
+ readonly id: "posts.likedByUser";
61
+ readonly category: "posts";
62
+ }>, Readonly<{
63
+ readonly id: "posts.byUser";
64
+ readonly category: "posts";
65
+ }>, Readonly<{
66
+ readonly id: "posts.comments";
67
+ readonly category: "posts";
68
+ }>, Readonly<{
69
+ readonly id: "posts.stats";
70
+ readonly category: "posts";
71
+ }>, Readonly<{
72
+ readonly id: "posts.get";
73
+ readonly category: "posts";
74
+ }>, Readonly<{
75
+ readonly id: "comments.replies";
76
+ readonly category: "comments";
77
+ }>, Readonly<{
78
+ readonly id: "notifications.list";
79
+ readonly category: "notifications";
80
+ }>, Readonly<{
81
+ readonly id: "notifications.count";
82
+ readonly category: "notifications";
83
+ }>, Readonly<{
84
+ readonly id: "notifications.getSettings";
85
+ readonly category: "notifications";
86
+ }>, Readonly<{
87
+ readonly id: "hashtags.search";
88
+ readonly category: "hashtags";
89
+ }>, Readonly<{
90
+ readonly id: "hashtags.trending";
91
+ readonly category: "hashtags";
92
+ }>, Readonly<{
93
+ readonly id: "hashtags.posts";
94
+ readonly category: "hashtags";
95
+ }>, Readonly<{
96
+ readonly id: "search.all";
97
+ readonly category: "search";
98
+ }>, Readonly<{
99
+ readonly id: "files.get";
100
+ readonly category: "files";
101
+ }>, Readonly<{
102
+ readonly id: "subscription.status";
103
+ readonly category: "subscription";
104
+ }>, Readonly<{
105
+ readonly id: "subscription.methods";
106
+ readonly category: "subscription";
107
+ }>, Readonly<{
108
+ readonly id: "verification.status";
109
+ readonly category: "verification";
110
+ }>, Readonly<{
111
+ readonly id: "platform.changelog";
112
+ readonly category: "platform";
113
+ }>, Readonly<{
114
+ readonly id: "platform.announcements";
115
+ readonly category: "platform";
116
+ }>, Readonly<{
117
+ readonly id: "platform.portal";
118
+ readonly category: "platform";
119
+ }>, Readonly<{
120
+ readonly id: "platform.status";
121
+ readonly category: "platform";
122
+ }>];
123
+ /** Имя операции, доступное в `cache({ operations: … })`. */
124
+ type CacheOperationId = (typeof CACHE_OPERATIONS)[number]['id'];
125
+ /** Раздел операции. */
126
+ type CacheOperationCategory = (typeof CACHE_OPERATIONS)[number]['category'];
127
+ /** Проверяет публичное имя кэшируемой операции. */
128
+ declare function isCacheOperationId(value: string): value is CacheOperationId;
129
+ /** Находит читающую операцию по стабильному семантическому ID. */
130
+ declare function cacheOperation(operationId: OperationId): (typeof CACHE_OPERATIONS)[number] | undefined;
131
+ //#endregion
132
+ //#region src/key.d.ts
209
133
  /**
210
134
  * Собирает ключ из значений, влияющих на адрес, тело или разобранный ответ.
211
135
  *
212
136
  * Заголовки и транспортные опции намеренно не входят. Если тело либо опция другого
213
137
  * плагина не сериализуются как JSON, запрос выполняется без кэша.
214
138
  */
215
- declare function buildCacheKey(route: CacheRouteId, request: RawRequestOptions): string | undefined;
216
-
139
+ declare function buildCacheKey(operation: CacheOperationId, request: OperationRequestOptions): string | undefined;
140
+ //#endregion
141
+ //#region src/plugin.d.ts
142
+ /** Режимы кэширования отдельного запроса. */
143
+ declare const CacheModes: Readonly<{
144
+ /** Отдать свежий кэш, иначе выполнить запрос и сохранить ответ. */
145
+ readonly Default: "default";
146
+ /** Пропустить сохранённое значение, выполнить запрос и перезаписать кэш. */
147
+ readonly Reload: "reload";
148
+ /** Не читать и не писать кэш для этого запроса. */
149
+ readonly NoStore: "no-store";
150
+ }>;
217
151
  /** Поведение кэша для отдельного запроса. */
218
- type CacheMode = 'default' | 'reload' | 'no-store';
152
+ type CacheMode = (typeof CacheModes)[keyof typeof CacheModes];
219
153
  /** Настройки плагина. */
220
154
  interface CacheOptions {
221
- /** Сколько миллисекунд хранить успешный ответ. */
222
- ttl: number;
223
- /** Какие операции itd-api кэшировать. */
224
- routes: readonly CacheRouteId[];
225
- /** Максимальное количество ответов. По умолчанию 500. */
226
- maxEntries?: number | undefined;
227
- /** Объединять ли одновременные одинаковые запросы. По умолчанию `true`. */
228
- deduplicate?: boolean | undefined;
155
+ /** Сколько миллисекунд хранить успешный ответ. */
156
+ ttl: number;
157
+ /** Какие операции itd-api кэшировать. */
158
+ operations: readonly CacheOperationId[];
159
+ /** Максимальное количество ответов. По умолчанию 500. */
160
+ maxEntries?: number | undefined;
161
+ /** Объединять ли одновременные одинаковые запросы. По умолчанию `true`. */
162
+ deduplicate?: boolean | undefined;
229
163
  }
230
164
  /** Плагин и управление созданным им хранилищем. */
231
- interface CachePlugin extends ItdPlugin {
232
- /** Количество готовых ответов во всех разделах кэша. */
233
- readonly size: number;
234
- /** Удаляет все ответы и не даёт выполняющимся запросам вернуть устаревший результат. */
235
- clear(): void;
236
- /** Удаляет все варианты названных маршрутов во всех подключённых клиентах. */
237
- invalidate(...routes: CacheRouteId[]): void;
238
- /**
239
- * Очищает список и счётчик уведомлений по событиям realtime.
240
- *
241
- * Сразу удаляет прежние значения и возвращает функцию отписки.
242
- */
243
- attachRealtime(stream: ItdRealtime): Unsubscribe;
165
+ interface CachePlugin extends ClientPlugin {
166
+ /** Количество готовых ответов во всех разделах кэша. */
167
+ readonly size: number;
168
+ /** Удаляет все ответы и не даёт выполняющимся запросам вернуть устаревший результат. */
169
+ clear(): void;
170
+ /** Удаляет все варианты названных операций во всех подключённых клиентах. */
171
+ invalidate(...operations: CacheOperationId[]): void;
172
+ /**
173
+ * Очищает список и счётчик уведомлений по событиям realtime.
174
+ *
175
+ * Сразу удаляет прежние значения и возвращает функцию отписки.
176
+ */
177
+ attachRealtime<C extends RealtimeContext>(stream: ItdRealtime<C>): Unsubscribe;
244
178
  }
245
179
  /** Создаёт TTL/LRU-кэш разобранных ответов itd-api. */
246
180
  declare function cache(options: CacheOptions): CachePlugin;
247
-
248
- /**
249
- * `@itd-api/cache` — TTL/LRU-кэш и дедупликация запросов для itd-api.
250
- *
251
- * @example
252
- * ```ts
253
- * import { cache } from '@itd-api/cache';
254
- *
255
- * itd.use(cache({
256
- * ttl: 60_000,
257
- * routes: ['users.get', 'posts.get', 'posts.list'],
258
- * }));
259
- * ```
260
- *
261
- * @packageDocumentation
262
- */
263
-
181
+ //#endregion
182
+ //#region src/index.d.ts
264
183
  declare module 'itd-api' {
265
- interface RequestOptions {
266
- /** Управление кэшем подключённого `@itd-api/cache`. */
267
- cache?: CacheMode | undefined;
268
- }
184
+ interface RequestExtensions {
185
+ /** Управление кэшем подключённого `@itd-api/cache`. */
186
+ cache?: CacheMode | undefined;
187
+ }
269
188
  }
270
-
271
- export { CACHE_ROUTES, CacheError, type CacheMode, type CacheOptions, type CachePlugin, type CacheRoute, type CacheRouteCategory, type CacheRouteId, buildCacheKey, cache, cacheRoute, isCacheRouteId };
189
+ //#endregion
190
+ export { CACHE_OPERATIONS, CacheError, type CacheMode, CacheModes, type CacheOperation, type CacheOperationCategory, type CacheOperationId, type CacheOptions, type CachePlugin, buildCacheKey, cache, cacheOperation, isCacheOperationId };
191
+ //# sourceMappingURL=index.d.ts.map