itd-api 0.10.3 → 0.11.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 +2 -1
- package/dist/events/index.cjs +27 -25
- package/dist/events/index.d.cts +3 -3
- package/dist/events/index.d.ts +3 -3
- package/dist/events/index.js +5 -5
- package/dist/index.cjs +136 -116
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -7
- package/dist/index.d.ts +18 -7
- package/dist/index.js +46 -30
- package/dist/index.js.map +1 -1
- package/dist/node/index.cjs +13 -13
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.js +5 -5
- package/dist/rest/index.cjs +43 -40
- package/dist/rest/index.cjs.map +1 -1
- package/dist/rest/index.d.cts +3 -3
- package/dist/rest/index.d.ts +3 -3
- package/dist/rest/index.js +6 -6
- package/dist/shared/{events-BVfqWyBw.cjs → events-C6tmj8aW.cjs} +63 -59
- package/dist/shared/events-C6tmj8aW.cjs.map +1 -0
- package/dist/shared/{events-Cp7ITueA.d.ts → events-CAb9G7Sf.d.ts} +2 -2
- package/dist/shared/{events-Cwj7UPAa.js → events-MWNcnfrq.js} +19 -15
- package/dist/shared/events-MWNcnfrq.js.map +1 -0
- package/dist/shared/{events-D0Wtt-If.d.cts → events-Sc75x6rT.d.cts} +2 -2
- package/dist/shared/{key-value-store-B5GYVEYZ.cjs → key-value-store-DYSPsqwq.cjs} +11 -14
- package/dist/shared/key-value-store-DYSPsqwq.cjs.map +1 -0
- package/dist/shared/{key-value-store-Bt2PSMxY.js → key-value-store-w1Dn5Pjb.js} +5 -8
- package/dist/shared/key-value-store-w1Dn5Pjb.js.map +1 -0
- package/dist/shared/{multi-storage-C3Ngtop1.js → multi-storage-BLBrGN9Q.js} +6 -6
- package/dist/shared/multi-storage-BLBrGN9Q.js.map +1 -0
- package/dist/shared/{multi-storage-s-fPtjoy.cjs → multi-storage-C7-Gz6Z7.cjs} +8 -8
- package/dist/shared/multi-storage-C7-Gz6Z7.cjs.map +1 -0
- package/dist/shared/{options-DjEtbVaf.cjs → options-5tywTYId.cjs} +13 -13
- package/dist/shared/{options-DjEtbVaf.cjs.map → options-5tywTYId.cjs.map} +1 -1
- package/dist/shared/{options-i4LrKfqx.js → options-BerKicCs.js} +3 -3
- package/dist/shared/{options-i4LrKfqx.js.map → options-BerKicCs.js.map} +1 -1
- package/dist/shared/{redact-DJV0XM3n.js → redact-C5oxIvcc.js} +79 -18
- package/dist/shared/redact-C5oxIvcc.js.map +1 -0
- package/dist/shared/{redact-lAmck1Z6.cjs → redact-DoC7lSsp.cjs} +109 -24
- package/dist/shared/redact-DoC7lSsp.cjs.map +1 -0
- package/dist/shared/{render-DRmuHoEy.d.ts → render-CBroJPcV.d.ts} +178 -252
- package/dist/shared/{render-CJO_L2CD.d.cts → render-DM7AhTZW.d.cts} +178 -252
- package/dist/shared/{render-BT74nC1l.js → render-DRh5_aRe.js} +128 -135
- package/dist/shared/render-DRh5_aRe.js.map +1 -0
- package/dist/shared/{render-CYJSDypQ.cjs → render-Dnc84B4M.cjs} +234 -241
- package/dist/shared/render-Dnc84B4M.cjs.map +1 -0
- package/dist/shared/{storage-DiDe0PZM.js → storage-86wiHeXD.js} +3 -3
- package/dist/shared/{storage-DiDe0PZM.js.map → storage-86wiHeXD.js.map} +1 -1
- package/dist/shared/{storage-CZJZoaz9.cjs → storage-CIjejZDt.cjs} +4 -4
- package/dist/shared/{storage-CZJZoaz9.cjs.map → storage-CIjejZDt.cjs.map} +1 -1
- package/dist/shared/{url-BLnX-LYt.d.cts → url-BOi-_mJT.d.cts} +143 -79
- package/dist/shared/{url-BLnX-LYt.d.ts → url-BOi-_mJT.d.ts} +143 -79
- package/dist/shared/{url-DS0-lrl-.js → url-Bg61sk_Y.js} +741 -598
- package/dist/shared/url-Bg61sk_Y.js.map +1 -0
- package/dist/shared/{url-BnO1aWsd.cjs → url-DTgkCWv5.cjs} +848 -717
- package/dist/shared/url-DTgkCWv5.cjs.map +1 -0
- package/dist/shared/{errors-BmP3TKoW.cjs → validate-CFx2dISs.cjs} +84 -5
- package/dist/shared/validate-CFx2dISs.cjs.map +1 -0
- package/dist/shared/{errors-GI10kZxk.js → validate-D7_kq3g5.js} +55 -6
- package/dist/shared/validate-D7_kq3g5.js.map +1 -0
- package/dist/web/index.cjs +4 -4
- package/dist/web/index.cjs.map +1 -1
- package/dist/web/index.js +3 -3
- package/package.json +1 -1
- package/dist/shared/errors-BmP3TKoW.cjs.map +0 -1
- package/dist/shared/errors-GI10kZxk.js.map +0 -1
- package/dist/shared/events-BVfqWyBw.cjs.map +0 -1
- package/dist/shared/events-Cwj7UPAa.js.map +0 -1
- package/dist/shared/key-value-store-B5GYVEYZ.cjs.map +0 -1
- package/dist/shared/key-value-store-Bt2PSMxY.js.map +0 -1
- package/dist/shared/multi-storage-C3Ngtop1.js.map +0 -1
- package/dist/shared/multi-storage-s-fPtjoy.cjs.map +0 -1
- package/dist/shared/redact-DJV0XM3n.js.map +0 -1
- package/dist/shared/redact-lAmck1Z6.cjs.map +0 -1
- package/dist/shared/render-BT74nC1l.js.map +0 -1
- package/dist/shared/render-CYJSDypQ.cjs.map +0 -1
- package/dist/shared/url-BnO1aWsd.cjs.map +0 -1
- package/dist/shared/url-DS0-lrl-.js.map +0 -1
package/dist/rest/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { A as SpanType, B as operationRetrySafety, C as ItdErrorCode, D as ReportReason, F as OPERATIONS, H as DEFAULT_RATE_LIMIT_BUCKET, L as isBuiltInOperationId, M as ViewSource, N as WallAccess, O as ReportTargetType, P as ITD_CATALOG, R as operationBucket, S as InteractionType, T as NotificationType, U as createClientRuntime, V as BUCKET_LIMITS,
|
|
2
|
-
import { A as
|
|
3
|
-
import { v as RuntimeMode } from "../shared/redact-
|
|
4
|
-
import { A as utcStampToIso, C as AUDIO_MIME_TYPES, D as isBuilder, E as comment, F as mapPage, I as createFeatureHost, L as ExtensibleOperationCatalog, N as PaginationMode, O as createStatusFeature, P as Paginator, S as ALLOWED_MIME_TYPES, T as VIDEO_MIME_TYPES, _ as poll, a as createShopOrderAccessStorage, b as parseHtml, c as ShopOrderStatus, d as isMyProfile, f as fromStream, g as post, h as report, i as MemoryShopOrderAccessStorage, j as NotificationsResource, k as toDate, l as ShopProductCategory, m as createResources, n as renderSpans, o as statusDays, p as fromUrl, r as createShopFeature, s as ShopConsentKind, t as SpanRenderFormat, u as ShopProductStatus, v as autoSpans, w as IMAGE_MIME_TYPES, x as parseMarkdown, y as markup } from "../shared/render-
|
|
5
|
-
import { c as FileTransferMode } from "../shared/options-
|
|
1
|
+
import { A as SpanType, B as operationRetrySafety, C as ItdErrorCode, D as ReportReason, F as OPERATIONS, H as DEFAULT_RATE_LIMIT_BUCKET, L as isBuiltInOperationId, M as ViewSource, N as WallAccess, O as ReportTargetType, P as ITD_CATALOG, R as operationBucket, S as InteractionType, T as NotificationType, U as createClientRuntime, V as BUCKET_LIMITS, X as OperationMethod, Z as RetrySafety, a as tokenProvider, b as FeedTab, c as normalizeNotification, d as canonicalNotificationType, dt as LIBRARY_VERSION, f as isKnownNotificationType, ft as RateLimitPacing, ht as installAsyncDisposeFallback, i as bearerToken, j as ViewReason, k as ServiceState, lt as STATUS_SERVICE, m as AttachmentType, mt as systemClock, n as formatNotificationText, p as AccessType, r as anonymousAuth, st as DEFAULT_BASE_URL, t as resolveNotificationUrl, v as CommentSort, w as LikesVisibility, x as IncidentKind, z as operationMethod } from "../shared/url-Bg61sk_Y.js";
|
|
2
|
+
import { A as isItdForbiddenError, C as ItdValidationError, D as isItdConflictError, E as isItdAuthError, F as isItdStateError, I as isItdValidationError, M as isItdPhoneVerificationError, N as isItdRateLimitError, O as isItdError, P as isItdServerError, S as ItdTimeoutError, T as isItdApiError, _ as ItdNotFoundError, a as ItdAbortError, b as ItdServerError, c as ItdAuthError, d as ItdError, f as ItdErrorKind, g as ItdNetworkError, h as ItdForbiddenError, j as isItdNotFoundError, k as isItdFileError, l as ItdConfigError, m as ItdFileErrorReason, o as ItdApiError, p as ItdFileError, s as ItdApiErrorKind, u as ItdConflictError, v as ItdPhoneVerificationError, w as TimeoutBudget, x as ItdStateError, y as ItdRateLimitError } from "../shared/validate-D7_kq3g5.js";
|
|
3
|
+
import { E as LogLevel, v as RuntimeMode } from "../shared/redact-C5oxIvcc.js";
|
|
4
|
+
import { A as utcStampToIso, C as AUDIO_MIME_TYPES, D as isBuilder, E as comment, F as mapPage, I as createFeatureHost, L as ExtensibleOperationCatalog, N as PaginationMode, O as createStatusFeature, P as Paginator, S as ALLOWED_MIME_TYPES, T as VIDEO_MIME_TYPES, _ as poll, a as createShopOrderAccessStorage, b as parseHtml, c as ShopOrderStatus, d as isMyProfile, f as fromStream, g as post, h as report, i as MemoryShopOrderAccessStorage, j as NotificationsResource, k as toDate, l as ShopProductCategory, m as createResources, n as renderSpans, o as statusDays, p as fromUrl, r as createShopFeature, s as ShopConsentKind, t as SpanRenderFormat, u as ShopProductStatus, v as autoSpans, w as IMAGE_MIME_TYPES, x as parseMarkdown, y as markup } from "../shared/render-DRh5_aRe.js";
|
|
5
|
+
import { c as FileTransferMode } from "../shared/options-BerKicCs.js";
|
|
6
6
|
//#region src/rest/client.ts
|
|
7
7
|
/**
|
|
8
8
|
* Минимальный клиент REST API итд.com.
|
|
@@ -295,6 +295,6 @@ function createRestClient(options = {}) {
|
|
|
295
295
|
return new ItdRestClient(options);
|
|
296
296
|
}
|
|
297
297
|
//#endregion
|
|
298
|
-
export { ALLOWED_MIME_TYPES, AUDIO_MIME_TYPES, AccessType, AttachmentType, BUCKET_LIMITS, CommentSort, DEFAULT_BASE_URL, DEFAULT_RATE_LIMIT_BUCKET, FeedTab, FileTransferMode, IMAGE_MIME_TYPES, IncidentKind, InteractionType, ItdAbortError, ItdApiError, ItdApiErrorKind, ItdAuthError, ItdConfigError, ItdConflictError, ItdError, ItdErrorCode, ItdErrorKind, ItdFileError, ItdFileErrorReason, ItdForbiddenError, ItdNetworkError, ItdNotFoundError, ItdPhoneVerificationError, ItdRateLimitError, ItdRestClient, ItdServerError, ItdStateError, ItdTimeoutError, ItdValidationError, LIBRARY_VERSION, LikesVisibility, MemoryShopOrderAccessStorage, NotificationType, OPERATIONS, PaginationMode, Paginator, RateLimitPacing, ReportReason, ReportTargetType, RetrySafety, RuntimeMode, STATUS_SERVICE, ServiceState, ShopConsentKind, ShopOrderStatus, ShopProductCategory, ShopProductStatus, SpanRenderFormat, SpanType, VIDEO_MIME_TYPES, ViewReason, ViewSource, WallAccess, anonymousAuth, autoSpans, bearerToken, canonicalNotificationType, comment, createRestClient, createShopFeature, createShopOrderAccessStorage, formatNotificationText, fromStream, fromUrl, isBuilder, isBuiltInOperationId, isItdApiError, isItdAuthError, isItdConflictError, isItdError, isItdFileError, isItdForbiddenError, isItdNotFoundError, isItdPhoneVerificationError, isItdRateLimitError, isItdServerError, isItdStateError, isItdValidationError, isKnownNotificationType, isMyProfile, mapPage, markup, normalizeNotification, operationBucket, operationMethod, operationRetrySafety, parseHtml, parseMarkdown, poll, post, renderSpans, report, resolveNotificationUrl, statusDays, systemClock, toDate, tokenProvider, utcStampToIso };
|
|
298
|
+
export { ALLOWED_MIME_TYPES, AUDIO_MIME_TYPES, AccessType, AttachmentType, BUCKET_LIMITS, CommentSort, DEFAULT_BASE_URL, DEFAULT_RATE_LIMIT_BUCKET, FeedTab, FileTransferMode, IMAGE_MIME_TYPES, IncidentKind, InteractionType, ItdAbortError, ItdApiError, ItdApiErrorKind, ItdAuthError, ItdConfigError, ItdConflictError, ItdError, ItdErrorCode, ItdErrorKind, ItdFileError, ItdFileErrorReason, ItdForbiddenError, ItdNetworkError, ItdNotFoundError, ItdPhoneVerificationError, ItdRateLimitError, ItdRestClient, ItdServerError, ItdStateError, ItdTimeoutError, ItdValidationError, LIBRARY_VERSION, LikesVisibility, LogLevel, MemoryShopOrderAccessStorage, NotificationType, OPERATIONS, OperationMethod, PaginationMode, Paginator, RateLimitPacing, ReportReason, ReportTargetType, RetrySafety, RuntimeMode, STATUS_SERVICE, ServiceState, ShopConsentKind, ShopOrderStatus, ShopProductCategory, ShopProductStatus, SpanRenderFormat, SpanType, TimeoutBudget, VIDEO_MIME_TYPES, ViewReason, ViewSource, WallAccess, anonymousAuth, autoSpans, bearerToken, canonicalNotificationType, comment, createRestClient, createShopFeature, createShopOrderAccessStorage, formatNotificationText, fromStream, fromUrl, isBuilder, isBuiltInOperationId, isItdApiError, isItdAuthError, isItdConflictError, isItdError, isItdFileError, isItdForbiddenError, isItdNotFoundError, isItdPhoneVerificationError, isItdRateLimitError, isItdServerError, isItdStateError, isItdValidationError, isKnownNotificationType, isMyProfile, mapPage, markup, normalizeNotification, operationBucket, operationMethod, operationRetrySafety, parseHtml, parseMarkdown, poll, post, renderSpans, report, resolveNotificationUrl, statusDays, systemClock, toDate, tokenProvider, utcStampToIso };
|
|
299
299
|
|
|
300
300
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const require_url = require("./url-
|
|
2
|
-
const
|
|
3
|
-
const require_redact = require("./redact-
|
|
1
|
+
const require_url = require("./url-DTgkCWv5.cjs");
|
|
2
|
+
const require_validate = require("./validate-CFx2dISs.cjs");
|
|
3
|
+
const require_redact = require("./redact-DoC7lSsp.cjs");
|
|
4
4
|
//#region src/core/emitter.ts
|
|
5
5
|
/**
|
|
6
6
|
* Минимальный типизированный источник событий.
|
|
@@ -68,20 +68,15 @@ var Emitter = class {
|
|
|
68
68
|
}
|
|
69
69
|
};
|
|
70
70
|
/**
|
|
71
|
-
* Сообщает об исключении из пользовательского обработчика
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* Ошибка чужого обработчика не должна ронять библиотеку, но и пропадать молча ей нельзя:
|
|
75
|
-
* иначе подписка, падающая на каждом событии, выглядит как её отсутствие.
|
|
71
|
+
* Сообщает об исключении из пользовательского обработчика события; без логгера —
|
|
72
|
+
* в {@link fallbackLogger}.
|
|
76
73
|
*
|
|
77
74
|
* @param scope о чьих событиях речь — попадает в текст сообщения
|
|
78
75
|
*
|
|
79
76
|
* @internal
|
|
80
77
|
*/
|
|
81
78
|
function reportListenerError(logger, scope, error) {
|
|
82
|
-
|
|
83
|
-
if (logger) logger.error(message, error);
|
|
84
|
-
else console.error(`[itd-api] ${message}`, error);
|
|
79
|
+
(logger ?? require_redact.fallbackLogger).error(`Ошибка в обработчике события ${scope}`, error);
|
|
85
80
|
}
|
|
86
81
|
//#endregion
|
|
87
82
|
//#region src/events/middleware.ts
|
|
@@ -103,7 +98,7 @@ function withEventMiddlewareSnapshot(middleware, capture) {
|
|
|
103
98
|
function deferEventMiddleware(source) {
|
|
104
99
|
const capture = () => {
|
|
105
100
|
const middleware = source.middleware();
|
|
106
|
-
if (typeof middleware !== "function") throw new
|
|
101
|
+
if (typeof middleware !== "function") throw new require_validate.ItdConfigError("events middleware() должен возвращать функцию обработки");
|
|
107
102
|
return captureEventMiddleware(middleware);
|
|
108
103
|
};
|
|
109
104
|
const deferred = (context, next) => capture()(context, next);
|
|
@@ -320,25 +315,28 @@ function setEventChannelGiveUpHook(channel, hook) {
|
|
|
320
315
|
function resolveEventChannelOptions(options = {}) {
|
|
321
316
|
const positiveInteger = (value, name) => {
|
|
322
317
|
if (value === void 0) return;
|
|
323
|
-
if (!Number.isInteger(value) || value < 0) throw new
|
|
318
|
+
if (!Number.isInteger(value) || value < 0) throw new require_validate.ItdConfigError(`events.${name} должен быть целым неотрицательным числом, получено: ${value}`);
|
|
324
319
|
};
|
|
325
320
|
const duration = (value, name) => {
|
|
326
|
-
if (!Number.isFinite(value) || value < 0) throw new
|
|
321
|
+
if (!Number.isFinite(value) || value < 0) throw new require_validate.ItdConfigError(`events.${name} должен быть числом не меньше 0, получено: ${value}`);
|
|
327
322
|
};
|
|
328
323
|
positiveInteger(options.maxAttempts, "maxAttempts");
|
|
329
324
|
positiveInteger(options.concurrency, "concurrency");
|
|
330
|
-
if (options.concurrency === 0) throw new
|
|
331
|
-
if (options.jitter !== void 0 && !(options.jitter >= 0 && options.jitter <= 1)) throw new
|
|
325
|
+
if (options.concurrency === 0) throw new require_validate.ItdConfigError("events.concurrency должен быть больше нуля");
|
|
326
|
+
if (options.jitter !== void 0 && !(options.jitter >= 0 && options.jitter <= 1)) throw new require_validate.ItdConfigError(`events.jitter должен быть в диапазоне 0…1, получено: ${options.jitter}`);
|
|
332
327
|
if (options.backoff !== void 0) {
|
|
333
|
-
if (!Array.isArray(options.backoff) || options.backoff.length === 0) throw new
|
|
328
|
+
if (!Array.isArray(options.backoff) || options.backoff.length === 0) throw new require_validate.ItdConfigError("events.backoff должен быть непустым списком пауз");
|
|
334
329
|
for (const delay of options.backoff) duration(delay, "backoff");
|
|
335
330
|
}
|
|
336
|
-
if (options.sequentialize !== void 0 && typeof options.sequentialize !== "function") throw new
|
|
331
|
+
if (options.sequentialize !== void 0 && typeof options.sequentialize !== "function") throw new require_validate.ItdConfigError("events.sequentialize должен быть функцией");
|
|
337
332
|
return Object.freeze({
|
|
338
333
|
...options,
|
|
339
334
|
...options.backoff ? { backoff: Object.freeze([...options.backoff]) } : {}
|
|
340
335
|
});
|
|
341
336
|
}
|
|
337
|
+
function describe(error) {
|
|
338
|
+
return error instanceof Error ? error.message : String(error);
|
|
339
|
+
}
|
|
342
340
|
/**
|
|
343
341
|
* Общая механика потока событий: соединение, переподключение с задержкой, обновление
|
|
344
342
|
* токена, реакция на среду, статусы и очередь обработчиков.
|
|
@@ -419,7 +417,7 @@ var EventChannel = class {
|
|
|
419
417
|
/** Добавляет промежуточный обработчик. @returns функция его удаления */
|
|
420
418
|
use(middleware) {
|
|
421
419
|
if (typeof middleware === "function") return this.#dispatcher.use(middleware);
|
|
422
|
-
if (typeof middleware !== "object" || middleware === null || typeof middleware.middleware !== "function") throw new
|
|
420
|
+
if (typeof middleware !== "object" || middleware === null || typeof middleware.middleware !== "function") throw new require_validate.ItdConfigError("events.use() принимает функцию обработки или объект с middleware()");
|
|
423
421
|
return this.#dispatcher.use(deferEventMiddleware(middleware));
|
|
424
422
|
}
|
|
425
423
|
/** Подписывает обработчик обновлений, подходящих под условие. */
|
|
@@ -447,6 +445,7 @@ var EventChannel = class {
|
|
|
447
445
|
}
|
|
448
446
|
/** Закрывает соединение и отменяет запланированные попытки. */
|
|
449
447
|
disconnect() {
|
|
448
|
+
const wasActive = this.#wanted;
|
|
450
449
|
this.#wanted = false;
|
|
451
450
|
this.#generation += 1;
|
|
452
451
|
this.#starting = void 0;
|
|
@@ -456,10 +455,11 @@ var EventChannel = class {
|
|
|
456
455
|
}
|
|
457
456
|
this.#detachEnvironment?.();
|
|
458
457
|
this.#detachEnvironment = void 0;
|
|
459
|
-
this.#abortSession(new
|
|
458
|
+
this.#abortSession(new require_validate.ItdAbortError("Событийное соединение остановлено"));
|
|
460
459
|
this.#attempt = 0;
|
|
461
460
|
this.#dispatcher.clearPending();
|
|
462
461
|
this.#setStatus(require_url.EventChannelStatus.Disconnected);
|
|
462
|
+
if (wasActive) this.#deps.logger?.info("поток событий остановлен");
|
|
463
463
|
}
|
|
464
464
|
/**
|
|
465
465
|
* Ждёт обработчики и полное завершение уже остановленной сессии соединения.
|
|
@@ -491,9 +491,10 @@ var EventChannel = class {
|
|
|
491
491
|
const session = this.#session;
|
|
492
492
|
if (!this.#wanted || !session) return;
|
|
493
493
|
const generation = session.generation;
|
|
494
|
-
this.#abortSession(new
|
|
494
|
+
this.#abortSession(new require_validate.ItdAbortError("Очередь событий переполнена"));
|
|
495
495
|
this.#setStatus(require_url.EventChannelStatus.Error);
|
|
496
496
|
const error = /* @__PURE__ */ new Error("Обработчики не успевают за потоком: очередь обновлений переполнена");
|
|
497
|
+
this.#deps.logger?.warn("очередь обновлений потока переполнена; соединение восстановится, когда обработчики её разберут");
|
|
497
498
|
this.#dispatcher.drain().then(() => {
|
|
498
499
|
if (this.#isCurrentGeneration(generation) && !this.#session) this.#scheduleReconnect(error);
|
|
499
500
|
});
|
|
@@ -501,7 +502,7 @@ var EventChannel = class {
|
|
|
501
502
|
/** Создаёт новую попытку соединения и выполняет её подготовку. */
|
|
502
503
|
async #startAttempt(reason) {
|
|
503
504
|
if (!this.#wanted) return;
|
|
504
|
-
this.#abortSession(new
|
|
505
|
+
this.#abortSession(new require_validate.ItdAbortError("Событийное соединение заменено новой попыткой"));
|
|
505
506
|
const session = this.#createSession(++this.#generation);
|
|
506
507
|
this.#session = session;
|
|
507
508
|
try {
|
|
@@ -536,7 +537,7 @@ var EventChannel = class {
|
|
|
536
537
|
await task;
|
|
537
538
|
} catch (error) {
|
|
538
539
|
if (this.#deps.initializationRequired) throw error;
|
|
539
|
-
this.#deps.logger?.
|
|
540
|
+
this.#deps.logger?.warn(`не удалось синхронизировать поток событий (${reason})`, error);
|
|
540
541
|
}
|
|
541
542
|
}
|
|
542
543
|
/** Запускает транспорт одной попытки. */
|
|
@@ -548,9 +549,11 @@ var EventChannel = class {
|
|
|
548
549
|
signal: session.controller.signal,
|
|
549
550
|
onOpen: () => {
|
|
550
551
|
if (!this.#isCurrentSession(session)) return;
|
|
552
|
+
const reconnected = this.#attempt > 0;
|
|
551
553
|
this.#attempt = 0;
|
|
552
554
|
session.resolveOpened();
|
|
553
555
|
this.#setStatus(require_url.EventChannelStatus.Connected);
|
|
556
|
+
this.#deps.logger?.info(reconnected ? "поток событий переподключён" : "поток событий подключён");
|
|
554
557
|
},
|
|
555
558
|
onEvent: (event) => {
|
|
556
559
|
if (this.#isCurrentSession(session)) this.#handleEvent(session, event);
|
|
@@ -594,8 +597,7 @@ var EventChannel = class {
|
|
|
594
597
|
return;
|
|
595
598
|
}
|
|
596
599
|
const message = event === "middlewareError" ? "Ошибка в промежуточном обработчике потока" : "Ошибка в обработчике обновления потока";
|
|
597
|
-
|
|
598
|
-
else console.error(`[itd-api] ${message}`, error);
|
|
600
|
+
(this.#deps.logger ?? require_redact.fallbackLogger).error(message, error);
|
|
599
601
|
}
|
|
600
602
|
#handleFailure(error) {
|
|
601
603
|
this.#abortSession(error);
|
|
@@ -626,6 +628,7 @@ var EventChannel = class {
|
|
|
626
628
|
}
|
|
627
629
|
const delay = reconnectDelay(this.#attempt, this.#options);
|
|
628
630
|
this.#attempt += 1;
|
|
631
|
+
this.#deps.logger?.warn(`поток событий оборван (${describe(error)}); переподключение ${this.#attempt} из ${this.#maxAttempts} через ${delay} мс`);
|
|
629
632
|
this.#emitEngine("error", {
|
|
630
633
|
error,
|
|
631
634
|
willReconnect: true
|
|
@@ -663,6 +666,7 @@ var EventChannel = class {
|
|
|
663
666
|
this.#abortSession(error);
|
|
664
667
|
this.#detachEnvironment?.();
|
|
665
668
|
this.#detachEnvironment = void 0;
|
|
669
|
+
this.#deps.logger?.warn(`поток событий остановлен без переподключения (${describe(error)}); для возобновления вызовите connect()`);
|
|
666
670
|
EVENT_CHANNEL_GIVEUP_HOOKS.get(this)?.();
|
|
667
671
|
this.#emitEngine("error", {
|
|
668
672
|
error,
|
|
@@ -877,7 +881,7 @@ var PollTransport = class {
|
|
|
877
881
|
signal
|
|
878
882
|
});
|
|
879
883
|
} catch (error) {
|
|
880
|
-
if (
|
|
884
|
+
if (require_validate.isItdAuthError(error)) throw new UnauthorizedStreamError();
|
|
881
885
|
throw error;
|
|
882
886
|
}
|
|
883
887
|
}
|
|
@@ -1202,22 +1206,22 @@ const NotificationUpdateOrigin = Object.freeze({
|
|
|
1202
1206
|
/** Проверяет форму фильтра уведомлений. */
|
|
1203
1207
|
function validateNotificationSelector(selector) {
|
|
1204
1208
|
if (typeof selector === "string") {
|
|
1205
|
-
if (selector.length === 0) throw new
|
|
1209
|
+
if (selector.length === 0) throw new require_validate.ItdConfigError("Тип уведомления не должен быть пустым");
|
|
1206
1210
|
return;
|
|
1207
1211
|
}
|
|
1208
1212
|
if (Array.isArray(selector)) {
|
|
1209
|
-
if (selector.length === 0 || selector.some((type) => typeof type !== "string" || !type)) throw new
|
|
1213
|
+
if (selector.length === 0 || selector.some((type) => typeof type !== "string" || !type)) throw new require_validate.ItdConfigError("Список типов уведомлений должен содержать непустые строки");
|
|
1210
1214
|
return;
|
|
1211
1215
|
}
|
|
1212
|
-
if (typeof selector !== "object" || selector === null) throw new
|
|
1216
|
+
if (typeof selector !== "object" || selector === null) throw new require_validate.ItdConfigError("Фильтр уведомлений должен быть строкой, списком или объектом");
|
|
1213
1217
|
const filter = selector;
|
|
1214
1218
|
if (filter.type !== void 0) validateNotificationSelector(filter.type);
|
|
1215
|
-
if (filter.actorId !== void 0 && typeof filter.actorId !== "string") throw new
|
|
1219
|
+
if (filter.actorId !== void 0 && typeof filter.actorId !== "string") throw new require_validate.ItdConfigError("Фильтр уведомлений: actorId должен быть строкой");
|
|
1216
1220
|
for (const field of ["entityId", "parentEntityId"]) {
|
|
1217
1221
|
const value = filter[field];
|
|
1218
|
-
if (value !== void 0 && value !== null && typeof value !== "string") throw new
|
|
1222
|
+
if (value !== void 0 && value !== null && typeof value !== "string") throw new require_validate.ItdConfigError(`Фильтр уведомлений: ${field} должен быть строкой или null`);
|
|
1219
1223
|
}
|
|
1220
|
-
if (filter.predicate !== void 0 && typeof filter.predicate !== "function") throw new
|
|
1224
|
+
if (filter.predicate !== void 0 && typeof filter.predicate !== "function") throw new require_validate.ItdConfigError("Фильтр уведомлений: predicate должен быть функцией");
|
|
1221
1225
|
}
|
|
1222
1226
|
/** Преобразует транспортный кадр в одно логическое обновление. */
|
|
1223
1227
|
function readNotificationEventsUpdate(event) {
|
|
@@ -1271,7 +1275,7 @@ function resolveNotificationEventsOptions(options = {}) {
|
|
|
1271
1275
|
resolveEventChannelOptions(options);
|
|
1272
1276
|
const duration = (value, name, min) => {
|
|
1273
1277
|
if (value === void 0) return;
|
|
1274
|
-
if (!Number.isFinite(value) || value < min) throw new
|
|
1278
|
+
if (!Number.isFinite(value) || value < min) throw new require_validate.ItdConfigError(`events.notifications.${name} должен быть числом не меньше ${min}, получено: ${value}`);
|
|
1275
1279
|
};
|
|
1276
1280
|
duration(options.pollInterval, "pollInterval", 1);
|
|
1277
1281
|
duration(options.idleTimeout, "idleTimeout", 0);
|
|
@@ -1382,8 +1386,8 @@ var NotificationEvents = class {
|
|
|
1382
1386
|
onUpdate(selectorOrHandler, selectedHandler) {
|
|
1383
1387
|
const selectAll = selectedHandler === void 0;
|
|
1384
1388
|
const handler = selectAll ? selectorOrHandler : selectedHandler;
|
|
1385
|
-
if (typeof handler !== "function") throw new
|
|
1386
|
-
if (!selectAll && typeof selectorOrHandler !== "function" && !Object.values(NotificationUpdateType).includes(selectorOrHandler)) throw new
|
|
1389
|
+
if (typeof handler !== "function") throw new require_validate.ItdConfigError("events.onUpdate() принимает функцию обработчика");
|
|
1390
|
+
if (!selectAll && typeof selectorOrHandler !== "function" && !Object.values(NotificationUpdateType).includes(selectorOrHandler)) throw new require_validate.ItdConfigError(`Неизвестный тип обновления потока: ${String(selectorOrHandler)}`);
|
|
1387
1391
|
let predicate;
|
|
1388
1392
|
if (selectAll) predicate = () => true;
|
|
1389
1393
|
else {
|
|
@@ -1393,7 +1397,7 @@ var NotificationEvents = class {
|
|
|
1393
1397
|
return this.#engine.onUpdate(predicate, handler);
|
|
1394
1398
|
}
|
|
1395
1399
|
onNotification(selector, handler) {
|
|
1396
|
-
if (typeof handler !== "function") throw new
|
|
1400
|
+
if (typeof handler !== "function") throw new require_validate.ItdConfigError("events.onNotification() принимает функцию обработчика");
|
|
1397
1401
|
if (typeof selector !== "function") validateNotificationSelector(selector);
|
|
1398
1402
|
const predicate = (context) => {
|
|
1399
1403
|
if (!isNotificationContext(context)) return false;
|
|
@@ -1480,7 +1484,7 @@ function createTransport(deps, options) {
|
|
|
1480
1484
|
const kind = options.transport ?? NotificationEventsTransport.Auto;
|
|
1481
1485
|
if (typeof kind === "object") return kind;
|
|
1482
1486
|
if (kind === NotificationEventsTransport.Poll || kind === NotificationEventsTransport.Auto && !require_redact.supportsStreamingBody()) {
|
|
1483
|
-
if (!deps.request) throw new
|
|
1487
|
+
if (!deps.request) throw new require_validate.ItdConfigError("Poll transport requires a notification request adapter");
|
|
1484
1488
|
return new PollTransport({
|
|
1485
1489
|
request: deps.request,
|
|
1486
1490
|
...deps.clock ? { clock: deps.clock } : {},
|
|
@@ -1508,7 +1512,7 @@ const OPEN = 1;
|
|
|
1508
1512
|
const NORMAL_CLOSURE = 1e3;
|
|
1509
1513
|
const UNAUTHORIZED_CLOSE_CODES = /* @__PURE__ */ new Set([1008, 4401]);
|
|
1510
1514
|
function validateDuration(value, name) {
|
|
1511
|
-
if (value !== void 0 && (!Number.isFinite(value) || value < 0)) throw new
|
|
1515
|
+
if (value !== void 0 && (!Number.isFinite(value) || value < 0)) throw new require_validate.ItdConfigError(`WebSocketTransport.${name} должен быть числом не меньше 0, получено: ${value}`);
|
|
1512
1516
|
}
|
|
1513
1517
|
function isWebSocketConnection(value) {
|
|
1514
1518
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -1565,12 +1569,12 @@ var WebSocketTransport = class {
|
|
|
1565
1569
|
#clock;
|
|
1566
1570
|
constructor(options = {}) {
|
|
1567
1571
|
const path = options.path ?? "/api/ws";
|
|
1568
|
-
if (typeof path !== "string" || path.trim() === "" || path.includes("?") || path.includes("#") || /^[a-z][a-z\d+.-]*:/i.test(path)) throw new
|
|
1569
|
-
if (options.webSocketImpl !== void 0 && typeof options.webSocketImpl !== "function") throw new
|
|
1570
|
-
if (options.classifyOpenFailure !== void 0 && typeof options.classifyOpenFailure !== "function") throw new
|
|
1572
|
+
if (typeof path !== "string" || path.trim() === "" || path.includes("?") || path.includes("#") || /^[a-z][a-z\d+.-]*:/i.test(path)) throw new require_validate.ItdConfigError("WebSocketTransport.path должен быть путём без query и fragment");
|
|
1573
|
+
if (options.webSocketImpl !== void 0 && typeof options.webSocketImpl !== "function") throw new require_validate.ItdConfigError("WebSocketTransport.webSocketImpl должен быть конструктором");
|
|
1574
|
+
if (options.classifyOpenFailure !== void 0 && typeof options.classifyOpenFailure !== "function") throw new require_validate.ItdConfigError("WebSocketTransport.classifyOpenFailure должен быть функцией");
|
|
1571
1575
|
const auth = options.auth ?? "auto";
|
|
1572
|
-
if (auth !== "auto" && auth !== "query" && auth !== "header") throw new
|
|
1573
|
-
if (auth === "header" && !options.webSocketImpl) throw new
|
|
1576
|
+
if (auth !== "auto" && auth !== "query" && auth !== "header") throw new require_validate.ItdConfigError(`Неизвестный способ авторизации WebSocket: ${String(auth)}`);
|
|
1577
|
+
if (auth === "header" && !options.webSocketImpl) throw new require_validate.ItdConfigError("WebSocketTransport.auth=\"header\" требует webSocketImpl с поддержкой заголовков");
|
|
1574
1578
|
validateDuration(options.idleTimeout, "idleTimeout");
|
|
1575
1579
|
validateDuration(options.keepAlive, "keepAlive");
|
|
1576
1580
|
validateDuration(options.handshakeTimeout, "handshakeTimeout");
|
|
@@ -1610,7 +1614,7 @@ var WebSocketTransport = class {
|
|
|
1610
1614
|
const detail = safeDetail(error, url, token);
|
|
1611
1615
|
throw new Error(`Не удалось создать WebSocket ${require_redact.redactUrl(url)}${detail ? `: ${detail}` : ""}`);
|
|
1612
1616
|
}
|
|
1613
|
-
if (!isWebSocketConnection(value)) throw new
|
|
1617
|
+
if (!isWebSocketConnection(value)) throw new require_validate.ItdConfigError("webSocketImpl вернул объект без WebSocket-методов addEventListener, send и close");
|
|
1614
1618
|
try {
|
|
1615
1619
|
value.binaryType = "arraybuffer";
|
|
1616
1620
|
} catch {}
|
|
@@ -1618,7 +1622,7 @@ var WebSocketTransport = class {
|
|
|
1618
1622
|
}
|
|
1619
1623
|
#globalImplementation() {
|
|
1620
1624
|
const implementation = Reflect.get(globalThis, "WebSocket");
|
|
1621
|
-
if (typeof implementation !== "function") throw new
|
|
1625
|
+
if (typeof implementation !== "function") throw new require_validate.ItdConfigError("В этой среде нет WebSocket: передайте реализацию через webSocketImpl");
|
|
1622
1626
|
return implementation;
|
|
1623
1627
|
}
|
|
1624
1628
|
#urls(baseUrl) {
|
|
@@ -1626,7 +1630,7 @@ var WebSocketTransport = class {
|
|
|
1626
1630
|
const socket = new URL(request);
|
|
1627
1631
|
if (request.protocol === "https:") socket.protocol = "wss:";
|
|
1628
1632
|
else if (request.protocol === "http:") socket.protocol = "ws:";
|
|
1629
|
-
else throw new
|
|
1633
|
+
else throw new require_validate.ItdConfigError(`WebSocketTransport требует baseUrl с http или https, получено: ${request.protocol}`);
|
|
1630
1634
|
return {
|
|
1631
1635
|
requestUrl: request.toString(),
|
|
1632
1636
|
socketUrl: socket.toString()
|
|
@@ -1847,7 +1851,7 @@ var NotificationEventsClient = class NotificationEventsClient extends Notificati
|
|
|
1847
1851
|
this.#runtime = runtime;
|
|
1848
1852
|
setNotificationEventsConnectGuard(this, () => {
|
|
1849
1853
|
if (!this.#disposed) return;
|
|
1850
|
-
throw new
|
|
1854
|
+
throw new require_validate.ItdStateError("Поток уже окончательно освобождён через dispose(); нельзя подключить его снова. Создайте новый");
|
|
1851
1855
|
});
|
|
1852
1856
|
}
|
|
1853
1857
|
/**
|
|
@@ -1949,12 +1953,12 @@ var EventRouter = class {
|
|
|
1949
1953
|
#routes = /* @__PURE__ */ new Map();
|
|
1950
1954
|
#fallback = [];
|
|
1951
1955
|
constructor(selector) {
|
|
1952
|
-
if (typeof selector !== "function") throw new
|
|
1956
|
+
if (typeof selector !== "function") throw new require_validate.ItdConfigError("EventRouter принимает функцию выбора маршрута");
|
|
1953
1957
|
this.#selector = selector;
|
|
1954
1958
|
}
|
|
1955
1959
|
/** Добавляет промежуточные обработчики к маршруту и возвращает функцию их удаления. */
|
|
1956
1960
|
route(key, ...middleware) {
|
|
1957
|
-
if (!isPropertyKey(key)) throw new
|
|
1961
|
+
if (!isPropertyKey(key)) throw new require_validate.ItdConfigError("Ключ маршрута событий должен быть PropertyKey");
|
|
1958
1962
|
const registration = this.#registration(middleware);
|
|
1959
1963
|
const registrations = this.#routes.get(key) ?? [];
|
|
1960
1964
|
registrations.push(registration);
|
|
@@ -1987,7 +1991,7 @@ var EventRouter = class {
|
|
|
1987
1991
|
const fallback = this.#fallback.flatMap(({ middleware }) => middleware).map(captureEventMiddleware);
|
|
1988
1992
|
return async (context, next) => {
|
|
1989
1993
|
const key = await this.#selector(context);
|
|
1990
|
-
if (key != null && !isPropertyKey(key)) throw new
|
|
1994
|
+
if (key != null && !isPropertyKey(key)) throw new require_validate.ItdConfigError("Функция выбора маршрута должна возвращать PropertyKey, null или undefined");
|
|
1991
1995
|
const route = key == null ? void 0 : routes.get(key);
|
|
1992
1996
|
const chain = route && route.length > 0 ? route : fallback;
|
|
1993
1997
|
if (chain.length === 0) {
|
|
@@ -1998,8 +2002,8 @@ var EventRouter = class {
|
|
|
1998
2002
|
};
|
|
1999
2003
|
}
|
|
2000
2004
|
#registration(middleware) {
|
|
2001
|
-
if (middleware.length === 0) throw new
|
|
2002
|
-
for (const item of middleware) if (typeof item !== "function") throw new
|
|
2005
|
+
if (middleware.length === 0) throw new require_validate.ItdConfigError("Маршрут должен содержать хотя бы один обработчик");
|
|
2006
|
+
for (const item of middleware) if (typeof item !== "function") throw new require_validate.ItdConfigError("Маршрут принимает только функции обработки");
|
|
2003
2007
|
return { middleware: [...middleware] };
|
|
2004
2008
|
}
|
|
2005
2009
|
};
|
|
@@ -2010,12 +2014,12 @@ function isPropertyKey(value) {
|
|
|
2010
2014
|
//#region src/events/composer.ts
|
|
2011
2015
|
function middlewareFunction(middleware) {
|
|
2012
2016
|
if (typeof middleware === "function") return middleware;
|
|
2013
|
-
if (typeof middleware !== "object" || middleware === null || typeof middleware.middleware !== "function") throw new
|
|
2017
|
+
if (typeof middleware !== "object" || middleware === null || typeof middleware.middleware !== "function") throw new require_validate.ItdConfigError("EventComposer принимает функцию обработки или объект с middleware()");
|
|
2014
2018
|
return deferEventMiddleware(middleware);
|
|
2015
2019
|
}
|
|
2016
2020
|
function middlewareGroup(group) {
|
|
2017
2021
|
const middleware = Array.isArray(group) ? group : [group];
|
|
2018
|
-
if (middleware.length === 0) throw new
|
|
2022
|
+
if (middleware.length === 0) throw new require_validate.ItdConfigError("Ветка EventComposer должна содержать хотя бы один middleware");
|
|
2019
2023
|
return middleware.map((item) => middlewareFunction(item));
|
|
2020
2024
|
}
|
|
2021
2025
|
function boundaryContinuation() {
|
|
@@ -2077,7 +2081,7 @@ var EventComposer = class EventComposer {
|
|
|
2077
2081
|
return this;
|
|
2078
2082
|
}
|
|
2079
2083
|
filter(predicate, ...middleware) {
|
|
2080
|
-
if (typeof predicate !== "function") throw new
|
|
2084
|
+
if (typeof predicate !== "function") throw new require_validate.ItdConfigError("EventComposer.filter() принимает функцию условия");
|
|
2081
2085
|
const child = new EventComposer(...middleware);
|
|
2082
2086
|
this.#middleware.push(deferEventMiddleware({ middleware: () => {
|
|
2083
2087
|
const nested = captureEventMiddleware(child.middleware());
|
|
@@ -2095,7 +2099,7 @@ var EventComposer = class EventComposer {
|
|
|
2095
2099
|
* динамической регистрации и числовых ключей используйте {@link EventRouter} напрямую.
|
|
2096
2100
|
*/
|
|
2097
2101
|
route(selector, routes, fallback) {
|
|
2098
|
-
if (typeof routes !== "object" || routes === null || Array.isArray(routes)) throw new
|
|
2102
|
+
if (typeof routes !== "object" || routes === null || Array.isArray(routes)) throw new require_validate.ItdConfigError("EventComposer.route() принимает объект именованных веток");
|
|
2099
2103
|
const router = new EventRouter(selector);
|
|
2100
2104
|
let registrations = 0;
|
|
2101
2105
|
for (const key of Reflect.ownKeys(routes)) {
|
|
@@ -2108,7 +2112,7 @@ var EventComposer = class EventComposer {
|
|
|
2108
2112
|
router.otherwise(...middlewareGroup(fallback));
|
|
2109
2113
|
registrations += 1;
|
|
2110
2114
|
}
|
|
2111
|
-
if (registrations === 0) throw new
|
|
2115
|
+
if (registrations === 0) throw new require_validate.ItdConfigError("EventComposer.route() требует хотя бы одну ветку или fallback");
|
|
2112
2116
|
return this.use(router);
|
|
2113
2117
|
}
|
|
2114
2118
|
/**
|
|
@@ -2118,7 +2122,7 @@ var EventComposer = class EventComposer {
|
|
|
2118
2122
|
* продолжает внешнюю цепочку.
|
|
2119
2123
|
*/
|
|
2120
2124
|
errorBoundary(handler, ...middleware) {
|
|
2121
|
-
if (typeof handler !== "function") throw new
|
|
2125
|
+
if (typeof handler !== "function") throw new require_validate.ItdConfigError("EventComposer.errorBoundary() принимает обработчик ошибки");
|
|
2122
2126
|
const child = new EventComposer(...middleware);
|
|
2123
2127
|
this.#middleware.push(deferEventMiddleware({ middleware: () => {
|
|
2124
2128
|
const nested = captureEventMiddleware(child.middleware());
|
|
@@ -2258,4 +2262,4 @@ Object.defineProperty(exports, "setNotificationEventsConnectGuard", {
|
|
|
2258
2262
|
}
|
|
2259
2263
|
});
|
|
2260
2264
|
|
|
2261
|
-
//# sourceMappingURL=events-
|
|
2265
|
+
//# sourceMappingURL=events-C6tmj8aW.cjs.map
|