itd-api 0.7.2 → 0.8.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.
Files changed (84) hide show
  1. package/README.md +12 -12
  2. package/dist/events/index.cjs +53 -0
  3. package/dist/events/index.d.cts +3 -0
  4. package/dist/events/index.d.ts +3 -0
  5. package/dist/events/index.js +5 -0
  6. package/dist/index.cjs +215 -194
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +66 -63
  9. package/dist/index.d.ts +66 -63
  10. package/dist/index.js +197 -179
  11. package/dist/index.js.map +1 -1
  12. package/dist/node/index.cjs +4 -4
  13. package/dist/node/index.d.cts +1 -1
  14. package/dist/node/index.d.ts +1 -1
  15. package/dist/node/index.js +4 -4
  16. package/dist/rest/index.cjs +20 -26
  17. package/dist/rest/index.cjs.map +1 -1
  18. package/dist/rest/index.d.cts +7 -7
  19. package/dist/rest/index.d.ts +7 -7
  20. package/dist/rest/index.js +14 -20
  21. package/dist/rest/index.js.map +1 -1
  22. package/dist/shared/{errors-DfU8M5eS.cjs → errors-BmP3TKoW.cjs} +3 -3
  23. package/dist/shared/{errors-DfU8M5eS.cjs.map → errors-BmP3TKoW.cjs.map} +1 -1
  24. package/dist/shared/{errors-Bhrd2fJd.js → errors-GI10kZxk.js} +3 -3
  25. package/dist/shared/{errors-Bhrd2fJd.js.map → errors-GI10kZxk.js.map} +1 -1
  26. package/dist/shared/events-Br2r7coi.d.cts +698 -0
  27. package/dist/shared/events-QyhQZrnC.d.ts +698 -0
  28. package/dist/shared/{websocket-BLR8eVJV.js → events-TfhKh26b.js} +770 -490
  29. package/dist/shared/events-TfhKh26b.js.map +1 -0
  30. package/dist/shared/{websocket-C_eI4H2o.cjs → events-iTteVsd_.cjs} +834 -518
  31. package/dist/shared/events-iTteVsd_.cjs.map +1 -0
  32. package/dist/shared/{multi-storage-CkvTUC5m.js → multi-storage-1AEZTczk.js} +4 -4
  33. package/dist/shared/{multi-storage-CkvTUC5m.js.map → multi-storage-1AEZTczk.js.map} +1 -1
  34. package/dist/shared/{multi-storage--yTEqiod.cjs → multi-storage-CCUgkqvI.cjs} +6 -6
  35. package/dist/shared/{multi-storage--yTEqiod.cjs.map → multi-storage-CCUgkqvI.cjs.map} +1 -1
  36. package/dist/shared/{options-DtATYdLr.js → options-BNP633A5.js} +8 -6
  37. package/dist/shared/options-BNP633A5.js.map +1 -0
  38. package/dist/shared/{options-Dg5N3r1V.cjs → options-BUfoHE9G.cjs} +8 -6
  39. package/dist/shared/options-BUfoHE9G.cjs.map +1 -0
  40. package/dist/shared/{cookies-DZwFq6kr.cjs → redact-DB9EMGJx.cjs} +301 -2
  41. package/dist/shared/redact-DB9EMGJx.cjs.map +1 -0
  42. package/dist/shared/{cookies-tX2sNwxb.js → redact-FNK29Fv-.js} +224 -3
  43. package/dist/shared/redact-FNK29Fv-.js.map +1 -0
  44. package/dist/shared/{render-DO0F5YSm.d.cts → render-BszcKF7S.d.cts} +430 -313
  45. package/dist/shared/{render-C6HRPs10.js → render-CiL1VS0b.js} +925 -582
  46. package/dist/shared/render-CiL1VS0b.js.map +1 -0
  47. package/dist/shared/{render-mcuELiYi.cjs → render-DNTESBSl.cjs} +967 -618
  48. package/dist/shared/render-DNTESBSl.cjs.map +1 -0
  49. package/dist/shared/{render-CgwKdOzu.d.ts → render-DVB7T8pm.d.ts} +430 -313
  50. package/dist/shared/{storage-BPJR_k4-.cjs → storage-BLmXmzKF.cjs} +2 -2
  51. package/dist/shared/{storage-BPJR_k4-.cjs.map → storage-BLmXmzKF.cjs.map} +1 -1
  52. package/dist/shared/{storage-D86edNCB.js → storage-CCxn0Kkv.js} +2 -2
  53. package/dist/shared/{storage-D86edNCB.js.map → storage-CCxn0Kkv.js.map} +1 -1
  54. package/dist/shared/{url-IU0xN9wX.js → url-B3ocFlHj.js} +434 -408
  55. package/dist/shared/url-B3ocFlHj.js.map +1 -0
  56. package/dist/shared/{url-DTfZ2toq.d.cts → url-Be9jlWRv.d.cts} +1228 -1188
  57. package/dist/shared/{url-DTfZ2toq.d.ts → url-Be9jlWRv.d.ts} +1228 -1188
  58. package/dist/shared/{url-BaMCQpYH.cjs → url-CFN1sT9S.cjs} +497 -465
  59. package/dist/shared/url-CFN1sT9S.cjs.map +1 -0
  60. package/dist/web/index.cjs +2 -2
  61. package/dist/web/index.js +2 -2
  62. package/package.json +16 -15
  63. package/dist/realtime/index.cjs +0 -165
  64. package/dist/realtime/index.cjs.map +0 -1
  65. package/dist/realtime/index.d.cts +0 -51
  66. package/dist/realtime/index.d.ts +0 -51
  67. package/dist/realtime/index.js +0 -120
  68. package/dist/realtime/index.js.map +0 -1
  69. package/dist/shared/auth-provider-CG8oCQ9F.cjs +0 -108
  70. package/dist/shared/auth-provider-CG8oCQ9F.cjs.map +0 -1
  71. package/dist/shared/auth-provider-mYqxsSVa.js +0 -91
  72. package/dist/shared/auth-provider-mYqxsSVa.js.map +0 -1
  73. package/dist/shared/cookies-DZwFq6kr.cjs.map +0 -1
  74. package/dist/shared/cookies-tX2sNwxb.js.map +0 -1
  75. package/dist/shared/options-Dg5N3r1V.cjs.map +0 -1
  76. package/dist/shared/options-DtATYdLr.js.map +0 -1
  77. package/dist/shared/render-C6HRPs10.js.map +0 -1
  78. package/dist/shared/render-mcuELiYi.cjs.map +0 -1
  79. package/dist/shared/url-BaMCQpYH.cjs.map +0 -1
  80. package/dist/shared/url-IU0xN9wX.js.map +0 -1
  81. package/dist/shared/websocket-BLR8eVJV.js.map +0 -1
  82. package/dist/shared/websocket-C_eI4H2o.cjs.map +0 -1
  83. package/dist/shared/websocket-DF7XIMiX.d.cts +0 -562
  84. package/dist/shared/websocket-DYKBr8HF.d.ts +0 -562
package/dist/index.cjs CHANGED
@@ -1,12 +1,64 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_url = require("./shared/url-BaMCQpYH.cjs");
3
- const require_errors = require("./shared/errors-DfU8M5eS.cjs");
4
- const require_cookies = require("./shared/cookies-DZwFq6kr.cjs");
5
- const require_render = require("./shared/render-mcuELiYi.cjs");
6
- const require_websocket = require("./shared/websocket-C_eI4H2o.cjs");
7
- const require_storage = require("./shared/storage-BPJR_k4-.cjs");
8
- const require_options = require("./shared/options-Dg5N3r1V.cjs");
9
- const require_multi_storage = require("./shared/multi-storage--yTEqiod.cjs");
2
+ const require_url = require("./shared/url-CFN1sT9S.cjs");
3
+ const require_errors = require("./shared/errors-BmP3TKoW.cjs");
4
+ const require_redact = require("./shared/redact-DB9EMGJx.cjs");
5
+ const require_render = require("./shared/render-DNTESBSl.cjs");
6
+ const require_options = require("./shared/options-BUfoHE9G.cjs");
7
+ const require_events = require("./shared/events-iTteVsd_.cjs");
8
+ const require_storage = require("./shared/storage-BLmXmzKF.cjs");
9
+ const require_multi_storage = require("./shared/multi-storage-CCUgkqvI.cjs");
10
+ //#region src/notifications-api.ts
11
+ var ClientNotifications = class extends require_render.NotificationsResource {
12
+ #createEvents;
13
+ #events;
14
+ constructor(http, createEvents) {
15
+ super(http);
16
+ this.#createEvents = createEvents;
17
+ }
18
+ get events() {
19
+ this.#events ??= this.#createEvents(this);
20
+ return this.#events;
21
+ }
22
+ };
23
+ /** Создаёт API уведомлений полного клиента. @internal */
24
+ function createNotificationsApi(http, createEvents) {
25
+ return new ClientNotifications(http, createEvents);
26
+ }
27
+ //#endregion
28
+ //#region src/operations/auth.ts
29
+ /** Чем закончился запрос входа. */
30
+ const SignInStatus = Object.freeze({
31
+ Authenticated: "authenticated",
32
+ OtpRequired: "otp_required"
33
+ });
34
+ function requireString(body, key, message) {
35
+ const value = require_url.pickString(body, key);
36
+ if (!value) throw new require_errors.ItdConfigError(message);
37
+ return value;
38
+ }
39
+ const AUTH_CHECK = require_url.passthroughOperation("auth.check");
40
+ const AUTH_SIGN_UP = require_url.defineBuiltInOperation("auth.signUp", (body) => requireString(body, "flowToken", "Сервер не вернул flowToken при регистрации"));
41
+ const AUTH_SIGN_IN = require_url.defineBuiltInOperation("auth.signIn", (body) => {
42
+ const accessToken = require_url.pickString(body, "accessToken");
43
+ return accessToken ? {
44
+ status: SignInStatus.Authenticated,
45
+ accessToken
46
+ } : {
47
+ status: SignInStatus.OtpRequired,
48
+ flowToken: require_url.pickString(body, "flowToken")
49
+ };
50
+ });
51
+ const AUTH_VERIFY_OTP = require_url.defineBuiltInOperation("auth.verifyOtp", (body) => requireString(body, "accessToken", "Сервер не вернул accessToken после подтверждения кода"));
52
+ const AUTH_REFRESH = require_url.defineBuiltInOperation("auth.refresh", (body) => require_url.pickString(body, "accessToken"));
53
+ const AUTH_RESEND_OTP = require_url.voidOperation("auth.resendOtp");
54
+ const AUTH_LOGOUT = require_url.voidOperation("auth.logout");
55
+ const AUTH_FORGOT_PASSWORD = require_url.defineBuiltInOperation("auth.forgotPassword", (body) => requireString(body, "flowToken", "Сервер не вернул flowToken при запросе сброса пароля"));
56
+ const AUTH_RESET_PASSWORD = require_url.voidOperation("auth.resetPassword");
57
+ const AUTH_CHANGE_PASSWORD = require_url.voidOperation("auth.changePassword");
58
+ const AUTH_SESSIONS = require_url.defineBuiltInOperation("auth.sessions", (body) => require_url.pickArray(body, "sessions"));
59
+ const AUTH_REVOKE_SESSION = require_url.voidOperation("auth.revokeSession");
60
+ const AUTH_REVOKE_OTHER_SESSIONS = require_url.voidOperation("auth.revokeOtherSessions");
61
+ //#endregion
10
62
  //#region src/session/jwt.ts
11
63
  /**
12
64
  * Разбирает строку base64url.
@@ -123,7 +175,7 @@ function resolveSessionConfig(options, runtime) {
123
175
  * достижимой из любой сборки, включая анонимную.
124
176
  */
125
177
  function createItdAuth(options, deps) {
126
- return new AuthManager(resolveSessionConfig(options, deps.config), deps.handler, deps.cookies, { onAccountChange: deps.onAccountChange });
178
+ return new AuthManager(resolveSessionConfig(options, deps.config), deps.http, deps.cookies, { onAccountChange: deps.onAccountChange });
127
179
  }
128
180
  /** Пути эндпоинтов авторизации. */
129
181
  const AUTH_PATHS = {
@@ -158,11 +210,6 @@ const AUTH_PATHS = {
158
210
  * ```
159
211
  */
160
212
  const TURNSTILE_SITE_KEY = "0x4AAAAAACHhxczw6fJGwPBg";
161
- function readAccessToken(payload) {
162
- if (typeof payload !== "object" || payload === null) return void 0;
163
- const token = payload.accessToken;
164
- return typeof token === "string" && token.length > 0 ? token : void 0;
165
- }
166
213
  /** Убирает поле, которое сохраняли промежуточные версии с поддержкой `getUserId()`. */
167
214
  function withoutLegacyUserId(session) {
168
215
  const clean = { ...session };
@@ -184,7 +231,7 @@ function nextAuthScope() {
184
231
  */
185
232
  var AuthManager = class {
186
233
  #config;
187
- #send;
234
+ #http;
188
235
  #jar;
189
236
  #emitter;
190
237
  #hooks;
@@ -223,12 +270,12 @@ var AuthManager = class {
223
270
  * воскресить уже очищенную сессию поверх `signOut`.
224
271
  */
225
272
  #authEpoch = 0;
226
- constructor(config, send, jar, hooks = {}) {
273
+ constructor(config, http, jar, hooks = {}) {
227
274
  this.#config = config;
228
- this.#send = send;
275
+ this.#http = http;
229
276
  this.#jar = jar;
230
277
  this.#hooks = hooks;
231
- this.#emitter = new require_websocket.Emitter((error) => require_websocket.reportListenerError(config.logger, "авторизации", error));
278
+ this.#emitter = new require_events.Emitter((error) => require_events.reportListenerError(config.logger, "авторизации", error));
232
279
  }
233
280
  /** Подписка на события авторизации. */
234
281
  get on() {
@@ -238,7 +285,7 @@ var AuthManager = class {
238
285
  get once() {
239
286
  return this.#emitter.once.bind(this.#emitter);
240
287
  }
241
- /** Снимает lifecycle-подписки при терминальном освобождении владельца. @internal */
288
+ /** Снимает служебные подписки при окончательном освобождении владельца. @internal */
242
289
  dispose() {
243
290
  this.#invalidateInFlight();
244
291
  this.#emitter.removeAllListeners();
@@ -294,7 +341,7 @@ var AuthManager = class {
294
341
  this.#externalIdentity = current;
295
342
  return token;
296
343
  }
297
- /** Меняет fallback и завершает realtime, только если фактически сменился аккаунт. */
344
+ /** Обновляет резервный идентификатор и закрывает события при смене аккаунта. */
298
345
  #transitionAuth(accessToken, rotateFallback = true) {
299
346
  const knownPrevious = this.#session !== void 0;
300
347
  const previous = this.#identityForToken(this.#session?.accessToken);
@@ -367,7 +414,7 @@ var AuthManager = class {
367
414
  }
368
415
  async #resolveDeviceId() {
369
416
  const session = await this.#loadSession();
370
- const deviceId = this.#config.deviceId ?? session?.deviceId ?? require_url.createDeviceId();
417
+ const deviceId = this.#config.deviceId ?? session?.deviceId ?? require_redact.createDeviceId();
371
418
  this.#deviceId = deviceId;
372
419
  if (session?.deviceId !== deviceId) await this.#saveSession({
373
420
  ...session ?? {},
@@ -522,7 +569,7 @@ var AuthManager = class {
522
569
  const refreshToken = this.#session?.refreshToken;
523
570
  if (!refreshToken) return;
524
571
  if (this.#jar.has("refresh_token")) return;
525
- this.#jar.set(this.#config.baseUrl, require_cookies.REFRESH_COOKIE, refreshToken, require_cookies.REFRESH_COOKIE_PATH);
572
+ this.#jar.set(this.#config.baseUrl, require_redact.REFRESH_COOKIE, refreshToken, require_redact.REFRESH_COOKIE_PATH);
526
573
  }
527
574
  #sessionFromConfig(auth) {
528
575
  if (!auth) return null;
@@ -566,16 +613,14 @@ var AuthManager = class {
566
613
  if (!this.#hasRefreshSession()) return this.#reloginOrNull();
567
614
  const epoch = this.#authEpoch;
568
615
  try {
569
- const accessToken = readAccessToken(await this.#send({
570
- operationId: "auth.refresh",
571
- method: require_url.operationMethod("auth.refresh"),
616
+ const accessToken = await this.#http.execute(AUTH_REFRESH, {
572
617
  path: AUTH_PATHS.refresh,
573
618
  skipAuth: true,
574
619
  skipAuthRefresh: true
575
- }));
620
+ });
576
621
  if (!accessToken) return this.#reloginOrNull();
577
622
  if (this.#authEpoch !== epoch) return this.#session?.accessToken ?? null;
578
- const rotated = this.#jar.getValue(require_cookies.REFRESH_COOKIE, this.#config.baseUrl + require_cookies.REFRESH_COOKIE_PATH);
623
+ const rotated = this.#jar.getValue(require_redact.REFRESH_COOKIE, this.#config.baseUrl + require_redact.REFRESH_COOKIE_PATH);
579
624
  this.#transitionAuth(accessToken, false);
580
625
  await this.#saveSession({
581
626
  ...this.#session ?? {},
@@ -639,9 +684,7 @@ var AuthManager = class {
639
684
  }
640
685
  async #performSignIn(credentials) {
641
686
  const turnstileToken = await this.#resolveTurnstileToken(credentials);
642
- const accessToken = readAccessToken(await this.#send({
643
- operationId: "auth.signIn",
644
- method: require_url.operationMethod("auth.signIn"),
687
+ const result = await this.#http.execute(AUTH_SIGN_IN, {
645
688
  path: AUTH_PATHS.signIn,
646
689
  body: {
647
690
  email: credentials.email,
@@ -650,8 +693,9 @@ var AuthManager = class {
650
693
  },
651
694
  skipAuth: true,
652
695
  skipAuthRefresh: true
653
- }));
654
- if (!accessToken) throw new require_errors.ItdConfigError("Вход по email и паролю требует подтверждения кодом из письма. Автоматический вход невозможен: воспользуйтесь itd.auth.signInWithOtp() и передайте полученный accessToken в конфигурацию клиента.");
696
+ });
697
+ if (result.status !== SignInStatus.Authenticated) throw new require_errors.ItdConfigError("Вход по email и паролю требует подтверждения кодом из письма. Автоматический вход невозможен: воспользуйтесь itd.auth.signInWithOtp() и передайте полученный accessToken в конфигурацию клиента.");
698
+ const accessToken = result.accessToken;
655
699
  this.#invalidateInFlight();
656
700
  this.#transitionAuth(accessToken);
657
701
  await this.#saveSession({
@@ -665,11 +709,12 @@ var AuthManager = class {
665
709
  };
666
710
  //#endregion
667
711
  //#region src/resources/auth.ts
668
- /** Чем закончился вход: сразу токеном или запросом кода подтверждения. */
669
- const SignInStatus = Object.freeze({
670
- Authenticated: "authenticated",
671
- OtpRequired: "otp_required"
672
- });
712
+ /**
713
+ * Результат входа.
714
+ *
715
+ * Сервер может как сразу выдать токен, так и потребовать код подтверждения — размеченное
716
+ * объединение делает оба случая явными.
717
+ */
673
718
  /**
674
719
  * Авторизация, сессии и пароли.
675
720
  *
@@ -687,7 +732,7 @@ var AuthResource = class extends require_render.BaseResource {
687
732
  * Без авторизации возвращает `authenticated: false` и `user: null`.
688
733
  */
689
734
  check(options = {}) {
690
- return this.http.operation("auth.check", {
735
+ return this.http.execute(AUTH_CHECK, {
691
736
  path: "/api/profile",
692
737
  ...options
693
738
  });
@@ -697,17 +742,14 @@ var AuthResource = class extends require_render.BaseResource {
697
742
  *
698
743
  * @returns `flowToken`, который нужно передать в {@link verifyOtp}
699
744
  */
700
- async signUp(credentials, options = {}) {
701
- const body = await this.http.operation("auth.signUp", {
745
+ signUp(credentials, options = {}) {
746
+ return this.http.execute(AUTH_SIGN_UP, {
702
747
  path: AUTH_PATHS.signUp,
703
748
  body: credentials,
704
749
  skipAuth: true,
705
750
  skipAuthRefresh: true,
706
751
  ...options
707
752
  });
708
- const flowToken = require_url.pickString(body, "flowToken");
709
- if (!flowToken) throw new require_errors.ItdConfigError("Сервер не вернул flowToken при регистрации");
710
- return flowToken;
711
753
  }
712
754
  /**
713
755
  * Выполняет вход.
@@ -720,25 +762,15 @@ var AuthResource = class extends require_render.BaseResource {
720
762
  * @param credentials email, пароль и обязательный токен капчи — см. {@link CaptchaCredentials}
721
763
  */
722
764
  async signIn(credentials, options = {}) {
723
- const body = await this.http.operation("auth.signIn", {
765
+ const result = await this.http.execute(AUTH_SIGN_IN, {
724
766
  path: AUTH_PATHS.signIn,
725
767
  body: credentials,
726
768
  skipAuth: true,
727
769
  skipAuthRefresh: true,
728
770
  ...options
729
771
  });
730
- const accessToken = require_url.pickString(body, "accessToken");
731
- if (accessToken) {
732
- await this.#auth.setAccessToken(accessToken);
733
- return {
734
- status: SignInStatus.Authenticated,
735
- accessToken
736
- };
737
- }
738
- return {
739
- status: SignInStatus.OtpRequired,
740
- flowToken: require_url.pickString(body, "flowToken")
741
- };
772
+ if (result.status === SignInStatus.Authenticated) await this.#auth.setAccessToken(result.accessToken);
773
+ return result;
742
774
  }
743
775
  /**
744
776
  * Подтверждает вход кодом из письма.
@@ -746,21 +778,19 @@ var AuthResource = class extends require_render.BaseResource {
746
778
  * Полученный токен сохраняется в клиенте автоматически.
747
779
  */
748
780
  async verifyOtp(input, options = {}) {
749
- const body = await this.http.operation("auth.verifyOtp", {
781
+ const accessToken = await this.http.execute(AUTH_VERIFY_OTP, {
750
782
  path: AUTH_PATHS.verifyOtp,
751
783
  body: input,
752
784
  skipAuth: true,
753
785
  skipAuthRefresh: true,
754
786
  ...options
755
787
  });
756
- const accessToken = require_url.pickString(body, "accessToken");
757
- if (!accessToken) throw new require_errors.ItdConfigError("Сервер не вернул accessToken после подтверждения кода");
758
788
  await this.#auth.setAccessToken(accessToken);
759
789
  return accessToken;
760
790
  }
761
791
  /** Отправляет код подтверждения повторно. */
762
792
  resendOtp(input, options = {}) {
763
- return this.http.operation("auth.resendOtp", {
793
+ return this.voidOperation(AUTH_RESEND_OTP, {
764
794
  path: AUTH_PATHS.resendOtp,
765
795
  body: input,
766
796
  skipAuth: true,
@@ -829,7 +859,7 @@ var AuthResource = class extends require_render.BaseResource {
829
859
  }
830
860
  /** Завершает текущую сессию на сервере и очищает локальную. */
831
861
  async logout(options = {}) {
832
- await this.http.operation("auth.logout", {
862
+ await this.voidOperation(AUTH_LOGOUT, {
833
863
  path: AUTH_PATHS.logout,
834
864
  skipAuthRefresh: true,
835
865
  ...options
@@ -857,17 +887,14 @@ var AuthResource = class extends require_render.BaseResource {
857
887
  *
858
888
  * @returns `flowToken`, который нужно передать в {@link resetPassword}
859
889
  */
860
- async forgotPassword(input, options = {}) {
861
- const body = await this.http.operation("auth.forgotPassword", {
890
+ forgotPassword(input, options = {}) {
891
+ return this.http.execute(AUTH_FORGOT_PASSWORD, {
862
892
  path: AUTH_PATHS.forgotPassword,
863
893
  body: input,
864
894
  skipAuth: true,
865
895
  skipAuthRefresh: true,
866
896
  ...options
867
897
  });
868
- const flowToken = require_url.pickString(body, "flowToken");
869
- if (!flowToken) throw new require_errors.ItdConfigError("Сервер не вернул flowToken при запросе сброса пароля");
870
- return flowToken;
871
898
  }
872
899
  /**
873
900
  * Устанавливает новый пароль по коду из письма.
@@ -876,7 +903,7 @@ var AuthResource = class extends require_render.BaseResource {
876
903
  * при нехватке любого отвечает `422`.
877
904
  */
878
905
  resetPassword(input, options = {}) {
879
- return this.http.operation("auth.resetPassword", {
906
+ return this.voidOperation(AUTH_RESET_PASSWORD, {
880
907
  path: AUTH_PATHS.resetPassword,
881
908
  body: input,
882
909
  skipAuth: true,
@@ -924,7 +951,7 @@ var AuthResource = class extends require_render.BaseResource {
924
951
  * ```
925
952
  */
926
953
  changePassword(input, options = {}) {
927
- return this.http.operation("auth.changePassword", {
954
+ return this.voidOperation(AUTH_CHANGE_PASSWORD, {
928
955
  path: AUTH_PATHS.changePassword,
929
956
  body: {
930
957
  currentPassword: input.currentPassword,
@@ -934,23 +961,22 @@ var AuthResource = class extends require_render.BaseResource {
934
961
  });
935
962
  }
936
963
  /** Загружает список активных сессий. У текущей поле `isCurrent` равно `true`. */
937
- async sessions(options = {}) {
938
- const body = await this.http.operation("auth.sessions", {
964
+ sessions(options = {}) {
965
+ return this.http.execute(AUTH_SESSIONS, {
939
966
  path: AUTH_PATHS.sessions,
940
967
  ...options
941
968
  });
942
- return require_url.pickArray(body, "sessions");
943
969
  }
944
970
  /** Завершает указанную сессию. */
945
971
  revokeSession(sessionId, options = {}) {
946
- return this.http.operation("auth.revokeSession", {
972
+ return this.voidOperation(AUTH_REVOKE_SESSION, {
947
973
  path: `${AUTH_PATHS.sessions}/${encodeURIComponent(sessionId)}`,
948
974
  ...options
949
975
  });
950
976
  }
951
977
  /** Завершает все сессии, кроме текущей. */
952
978
  revokeOtherSessions(options = {}) {
953
- return this.http.operation("auth.revokeOtherSessions", {
979
+ return this.voidOperation(AUTH_REVOKE_OTHER_SESSIONS, {
954
980
  path: AUTH_PATHS.sessions,
955
981
  ...options
956
982
  });
@@ -1014,8 +1040,6 @@ function createManagedClient(options, internals) {
1014
1040
  var ItdClient = class ItdClient {
1015
1041
  #runtime;
1016
1042
  #features;
1017
- /** Порождённые потоки уведомлений — чтобы `close()` мог закрыть их разом. */
1018
- #streams = /* @__PURE__ */ new Set();
1019
1043
  /** Общий результат терминальной очистки для идемпотентных повторных вызовов. */
1020
1044
  #disposePromise;
1021
1045
  /** Ресурсы конвейера запросов; создаются при первом обращении. */
@@ -1076,33 +1100,71 @@ var ItdClient = class ItdClient {
1076
1100
  return this.#resources.telemetry;
1077
1101
  }
1078
1102
  constructor(options = {}) {
1103
+ const notificationEventsOptions = require_events.resolveNotificationEventsOptions(options.events?.notifications);
1079
1104
  const internals = CLIENT_INTERNALS.get(options) ?? {};
1080
1105
  const catalog = new require_render.ExtensibleOperationCatalog(require_url.ITD_CATALOG);
1106
+ let featureHost;
1081
1107
  this.#runtime = require_url.createClientRuntime(options, {
1082
1108
  catalog,
1083
1109
  queues: internals.queues,
1084
1110
  assertActive: (action) => assertClientActive(this, action),
1085
1111
  auth: (deps) => createItdAuth(options, {
1086
1112
  ...deps,
1087
- onAccountChange: () => this.#disconnectStreams()
1113
+ onAccountChange: () => featureHost?.stop()
1088
1114
  })
1089
1115
  });
1090
- this.#features = new require_render.FeatureRegistry({
1091
- http: this.#runtime.http,
1092
- services: this.#runtime.services,
1093
- serviceOverrides: this.#runtime.config.services,
1116
+ this.#features = featureHost = require_render.createFeatureHost(this.#runtime, {
1094
1117
  catalog,
1095
- baseUrl: this.#runtime.config.baseUrl,
1096
- clock: this.#runtime.config.clock,
1097
- logger: this.#runtime.config.logger,
1098
- assertActive: (action) => assertClientActive(this, action),
1099
- registerBucket: (name, definition) => this.#runtime.registerRateLimitBucket(name, definition)
1118
+ assertActive: (action) => assertClientActive(this, action)
1100
1119
  });
1101
1120
  const status = this.#features.install(require_render.createStatusFeature());
1102
1121
  this.#resources = require_render.createResources({
1103
1122
  http: this.#runtime.http,
1104
- fetch: this.#runtime.config.fetch,
1105
- status
1123
+ files: this.#features.files,
1124
+ status,
1125
+ createNotifications: (http) => createNotificationsApi(http, (notifications) => {
1126
+ let events;
1127
+ let lifecycleGeneration = 0;
1128
+ let lifecycleActive = false;
1129
+ let unregister;
1130
+ const releaseAfterDrain = (generation) => {
1131
+ events.drain().then(() => {
1132
+ if (lifecycleActive || generation !== lifecycleGeneration) return;
1133
+ unregister?.();
1134
+ unregister = void 0;
1135
+ });
1136
+ };
1137
+ events = new require_events.NotificationEvents({
1138
+ connection: this.#runtime.connection(),
1139
+ request: ({ operationId, path, query, signal }) => this.#runtime.http.execute(require_events.EVENT_OPERATIONS[operationId], {
1140
+ path,
1141
+ query,
1142
+ signal
1143
+ }),
1144
+ getAuthIdentity: () => this.#runtime.auth.getCurrentAuthIdentity(),
1145
+ getAuthScope: () => this.#runtime.auth.getAuthScope(),
1146
+ fetchUnreadCount: (signal) => notifications.count({ signal }),
1147
+ onConnect: () => {
1148
+ lifecycleGeneration += 1;
1149
+ unregister ??= this.#features.manage({
1150
+ kind: `notifications:${events.transport}`,
1151
+ stop: () => {
1152
+ if (lifecycleActive) events.disconnect();
1153
+ },
1154
+ drain: () => events.drain()
1155
+ });
1156
+ lifecycleActive = true;
1157
+ },
1158
+ onClose: () => {
1159
+ lifecycleActive = false;
1160
+ releaseAfterDrain(++lifecycleGeneration);
1161
+ },
1162
+ logger: this.#runtime.config.logger,
1163
+ clock: this.#runtime.config.clock
1164
+ }, notificationEventsOptions);
1165
+ require_events.setNotificationEventsConnectGuard(events, () => assertClientActive(this, "подключить канал событий уведомлений"));
1166
+ return events;
1167
+ })
1106
1168
  });
1107
1169
  CLIENT_PLUGIN_REGISTRIES.set(this, this.#runtime.plugins);
1108
1170
  }
@@ -1146,19 +1208,19 @@ var ItdClient = class ItdClient {
1146
1208
  return this.#runtime.rateLimitState();
1147
1209
  }
1148
1210
  /**
1149
- * Устанавливает предметный модуль поверх общей сессии и request pipeline клиента.
1211
+ * Устанавливает предметный модуль с общей сессией и обработкой запросов клиента.
1150
1212
  *
1151
- * Сервисы, операции и бакеты feature регистрируются до синхронного `setup()`. Возвращаемое
1152
- * значение — типизированный API модуля; повторное имя feature отклоняется.
1213
+ * Сервисы, операции и бакеты регистрируются до синхронного `setup()`. Возвращает
1214
+ * типизированный API модуля.
1153
1215
  */
1154
1216
  install(feature) {
1155
1217
  return this.#features.install(feature);
1156
1218
  }
1157
1219
  /**
1158
- * Устанавливает feature и публикует его API как readonly-свойство этого же клиента.
1220
+ * Устанавливает модуль и добавляет его API в свойство клиента только для чтения.
1159
1221
  *
1160
1222
  * Возвращаемое пересечение сохраняет тип уже подключённых свойств, поэтому вызовы можно
1161
- * объединять в цепочку: `new ItdClient().withFeature('chats', chatsFeature)`.
1223
+ * объединять в цепочку: `new ItdClient().withFeature('pixelBattle', pixelBattleFeature)`.
1162
1224
  */
1163
1225
  withFeature(key, feature) {
1164
1226
  assertClientActive(this, "установить feature");
@@ -1174,20 +1236,18 @@ var ItdClient = class ItdClient {
1174
1236
  });
1175
1237
  return this;
1176
1238
  }
1177
- /** Имена установленных feature в порядке установки. */
1239
+ /** Имена установленных модулей в порядке установки. */
1178
1240
  featureNames() {
1179
1241
  return this.#features.names();
1180
1242
  }
1181
- /** Установлен ли feature с таким именем. */
1243
+ /** Установлен ли модуль с таким именем. */
1182
1244
  hasFeature(name) {
1183
1245
  return this.#features.has(name);
1184
1246
  }
1185
1247
  /**
1186
1248
  * Подключает плагин.
1187
1249
  *
1188
- * Плагин может независимо регистрировать transformer логической операции и interceptor
1189
- * транспортной попытки. Оба контракта охватывают все методы клиента. Подключать плагин
1190
- * можно в любой момент, но обычно это делают сразу после создания клиента.
1250
+ * Плагин может регистрировать обёртки операций и перехватчики сетевых попыток.
1191
1251
  *
1192
1252
  * @throws {ItdConfigError} если плагин задан неверно или уже подключён
1193
1253
  * @throws {ItdStateError} если клиент уже освобождён через {@link dispose}
@@ -1290,85 +1350,27 @@ var ItdClient = class ItdClient {
1290
1350
  return this.#runtime.auth.on(event, listener);
1291
1351
  }
1292
1352
  /**
1293
- * Создаёт поток уведомлений в реальном времени.
1294
- *
1295
- * Каждый вызов даёт новый независимый поток; обычно он нужен один на приложение.
1296
- * Соединение поднимается методом `connect()` и держится само. Замена авторизации на токен
1297
- * другого пользователя завершает все потоки клиента; смена только сессии их не затрагивает.
1298
- *
1299
- * @example
1300
- * ```ts
1301
- * import { NotificationType } from 'itd-api';
1302
- *
1303
- * const stream = itd.realtime();
1304
- *
1305
- * stream.onNotification(NotificationType.PostComment, async ({ update }) => {
1306
- * await handleComment(update.data.notification);
1307
- * });
1308
- * stream.on('unreadCount', (count) => setBadge(count));
1309
- *
1310
- * await stream.connect();
1311
- * ```
1312
- *
1313
- * @throws {ItdStateError} если клиент уже освобождён через {@link dispose}
1314
- */
1315
- realtime(options = {}) {
1316
- assertClientActive(this, "создать realtime-поток");
1317
- let stream;
1318
- stream = new require_websocket.ItdRealtime({
1319
- baseUrl: this.#runtime.config.baseUrl,
1320
- fetch: this.#runtime.config.fetch,
1321
- request: ({ operationId, path, query, signal }) => this.#runtime.http.operation(operationId, {
1322
- path,
1323
- query,
1324
- signal
1325
- }),
1326
- baseHeaders: (url) => this.#runtime.platformHeaders(url),
1327
- getAuthIdentity: () => this.#runtime.auth.getCurrentAuthIdentity(),
1328
- getAuthScope: () => this.#runtime.auth.getAuthScope(),
1329
- getToken: () => this.#runtime.auth.token(),
1330
- refresh: () => this.#runtime.auth.onUnauthorized(),
1331
- fetchUnreadCount: () => this.notifications.count(),
1332
- onConnect: () => this.#streams.add(stream),
1333
- onClose: () => this.#streams.delete(stream),
1334
- logger: this.#runtime.config.logger,
1335
- clock: this.#runtime.config.clock
1336
- }, options);
1337
- require_websocket.setRealtimeConnectGuard(stream, () => assertClientActive(this, "подключить realtime-поток"));
1338
- this.#streams.add(stream);
1339
- return stream;
1340
- }
1341
- /**
1342
1353
  * Освобождает ресурсы клиента: закрывает все потоки уведомлений, отправляет открытые
1343
1354
  * накопители {@link telemetry}, затем останавливает очередь запросов.
1344
1355
  *
1345
- * Метод дожидается активных обработчиков потока, но не дольше `shutdownTimeout`. После
1346
- * вызова клиентом можно пользоваться снова; ранее созданный поток можно запустить
1347
- * повторным `connect()`.
1356
+ * Метод дожидается завершения активных обработчиков и освобождения ресурсов остановленных
1357
+ * событийных соединений, но не дольше `shutdownTimeout`. После вызова клиентом можно
1358
+ * пользоваться снова; ранее созданный поток можно запустить повторным `connect()`.
1348
1359
  *
1349
1360
  * Общая очередь, полученная от {@link ItdAccounts}, не останавливается: её гасит сам
1350
1361
  * контейнер, когда закрывает все аккаунты разом.
1351
1362
  *
1352
1363
  * Терминальное освобождение — это {@link dispose}.
1353
1364
  *
1354
- * @throws {ItdStateError} если обработчики потока не завершились за отведённый срок
1365
+ * @throws {ItdStateError} если остановка событийного соединения не завершилась за отведённый срок
1355
1366
  */
1356
1367
  async close() {
1357
1368
  return this.#close(false);
1358
1369
  }
1359
1370
  async #close(disposeCleanup) {
1360
- const streams = this.#disconnectStreams();
1361
1371
  if (disposeCleanup) this.#resources.prepareTelemetryClose();
1362
- const { shutdownTimeout, clock } = this.#runtime.config;
1363
- const deadline = require_url.createDeadline(shutdownTimeout, clock);
1364
- let stuck = [];
1365
1372
  const errors = [];
1366
1373
  try {
1367
- try {
1368
- stuck = (await Promise.all(streams.map(async (stream) => await deadline.wait(stream.drain()) ? void 0 : stream))).filter((stream) => stream !== void 0);
1369
- } catch (error) {
1370
- errors.push(error);
1371
- }
1372
1374
  try {
1373
1375
  await this.#features.close();
1374
1376
  } catch (error) {
@@ -1380,10 +1382,8 @@ var ItdClient = class ItdClient {
1380
1382
  errors.push(error);
1381
1383
  }
1382
1384
  } finally {
1383
- deadline.cancel();
1384
1385
  this.#runtime.close();
1385
1386
  }
1386
- if (stuck.length > 0) errors.push(new require_errors.ItdStateError(`обработчики потоков (${stuck.map((stream) => stream.transport).join(", ")}) не завершились за ${shutdownTimeout} мс; ожидание прекращено`));
1387
1387
  if (errors.length === 1) throw errors[0];
1388
1388
  if (errors.length > 1) throw new AggregateError(errors, "Не удалось закрыть клиент");
1389
1389
  }
@@ -1393,10 +1393,11 @@ var ItdClient = class ItdClient {
1393
1393
  *
1394
1394
  * Терминальное состояние устанавливается сразу при первом вызове. После этого новые
1395
1395
  * запросы, подключение плагинов, регистрация сервисов и создание или повторный запуск
1396
- * realtime-потоков завершаются с {@link ItdStateError}. Повторные вызовы возвращают
1396
+ * событийных каналов завершаются с {@link ItdStateError}. Повторные вызовы возвращают
1397
1397
  * тот же результат очистки.
1398
1398
  *
1399
- * Ожидание обработчиков потока и операций плагинов ограничено `shutdownTimeout`.
1399
+ * Ожидание остановки событийных соединений и операций плагинов ограничено
1400
+ * `shutdownTimeout`.
1400
1401
  *
1401
1402
  * @example
1402
1403
  * ```ts
@@ -1430,13 +1431,6 @@ var ItdClient = class ItdClient {
1430
1431
  }
1431
1432
  if (errors.length > 0) throw new AggregateError(errors, "Не удалось освободить клиент");
1432
1433
  }
1433
- /** Завершает потоки до того, как запросы начнут использовать другой аккаунт. */
1434
- #disconnectStreams() {
1435
- const streams = [...this.#streams];
1436
- for (const stream of streams) stream.disconnect();
1437
- this.#streams.clear();
1438
- return streams;
1439
- }
1440
1434
  /** Позволяет использовать клиент с `await using`. */
1441
1435
  [Symbol.asyncDispose]() {
1442
1436
  return this.dispose();
@@ -1502,6 +1496,25 @@ function createClient(options = {}) {
1502
1496
  function validateAccountName(name) {
1503
1497
  if (typeof name !== "string" || name.trim() === "") throw new require_errors.ItdConfigError("имя аккаунта должно быть непустой строкой");
1504
1498
  }
1499
+ /** Проверяет фабрики до создания первого аккаунта. */
1500
+ function resolveAccountFeatures(features) {
1501
+ if (features === void 0) return [];
1502
+ if (!Array.isArray(features)) throw new require_errors.ItdConfigError("features должен быть массивом фабрик подключаемых модулей");
1503
+ const keys = /* @__PURE__ */ new Set();
1504
+ return features.map((feature, index) => {
1505
+ if (typeof feature !== "object" || feature === null || typeof feature.create !== "function") throw new require_errors.ItdConfigError(`features[${index}] должен предоставлять create()`);
1506
+ if (feature.key !== void 0) {
1507
+ if (typeof feature.key !== "string" || feature.key.trim() === "" || feature.key !== feature.key.trim()) throw new require_errors.ItdConfigError(`features[${index}].key должен быть непустой строкой без пробелов`);
1508
+ if (keys.has(feature.key)) throw new require_errors.ItdConfigError(`Свойство подключаемого модуля «${feature.key}» объявлено повторно`);
1509
+ keys.add(feature.key);
1510
+ }
1511
+ const create = feature.create.bind(feature);
1512
+ return Object.freeze({
1513
+ ...feature.key === void 0 ? {} : { key: feature.key },
1514
+ create
1515
+ });
1516
+ });
1517
+ }
1505
1518
  const DISPOSED_ACCOUNTS = /* @__PURE__ */ new WeakSet();
1506
1519
  function assertAccountsActive(accounts, action) {
1507
1520
  if (!DISPOSED_ACCOUNTS.has(accounts)) return;
@@ -1553,6 +1566,8 @@ var ItdAccounts = class ItdAccounts {
1553
1566
  #eventUnsubscribers = /* @__PURE__ */ new Map();
1554
1567
  /** Плагины для всех: и для уже заведённых аккаунтов, и для будущих. */
1555
1568
  #plugins;
1569
+ /** Фабрики модулей для новых и восстанавливаемых аккаунтов. */
1570
+ #features;
1556
1571
  /** Имена плагинов, чья асинхронная очистка ещё не завершилась. */
1557
1572
  #removingPlugins = /* @__PURE__ */ new Set();
1558
1573
  /** Общая очередь. `undefined`, когда у каждого аккаунта своя. */
@@ -1563,17 +1578,18 @@ var ItdAccounts = class ItdAccounts {
1563
1578
  /** Общий результат терминальной очистки для идемпотентных повторных вызовов. */
1564
1579
  #disposePromise;
1565
1580
  constructor(options = {}) {
1566
- const { storage, plugins, rateLimitScope, ...base } = options;
1581
+ const { storage, plugins, features, rateLimitScope, ...base } = options;
1567
1582
  if (rateLimitScope !== void 0 && rateLimitScope !== "account" && rateLimitScope !== "shared") throw new require_errors.ItdConfigError("rateLimitScope должен быть 'account' или 'shared'");
1568
1583
  this.#base = base;
1569
1584
  this.#storage = storage ?? new require_multi_storage.MemoryMultiTokenStorage();
1570
1585
  this.#plugins = require_url.orderPluginDefinitions(plugins ?? []);
1586
+ this.#features = resolveAccountFeatures(features);
1571
1587
  this.#rateLimitScope = rateLimitScope ?? "shared";
1572
1588
  const rateLimit = this.#rateLimitScope === "shared" ? require_url.resolveRateLimit(base.rateLimit, require_url.ITD_CATALOG) : void 0;
1573
1589
  this.#queues = rateLimit ? new require_url.RequestQueuePool(rateLimit, base.clock ?? require_url.systemClock) : void 0;
1574
1590
  const logger = typeof base.logger === "object" ? base.logger : void 0;
1575
1591
  this.#logger = logger;
1576
- this.#emitter = new require_websocket.Emitter((error) => require_websocket.reportListenerError(logger, "аккаунтов", error));
1592
+ this.#emitter = new require_events.Emitter((error) => require_events.reportListenerError(logger, "аккаунтов", error));
1577
1593
  }
1578
1594
  /** Общее хранилище сессий — то же, что передано опцией `storage`. */
1579
1595
  get storage() {
@@ -1594,7 +1610,7 @@ var ItdAccounts = class ItdAccounts {
1594
1610
  /**
1595
1611
  * Заводит аккаунт.
1596
1612
  *
1597
- * Возвращается обычный `ItdClient` — со всеми ресурсами, плагинами и `realtime()`.
1613
+ * Возвращается обычный `ItdClient` — со всеми ресурсами, плагинами и каналом событий.
1598
1614
  * Хранилище ему подставляется само: срез общего по имени аккаунта.
1599
1615
  *
1600
1616
  * Опция `auth` не обязательна: когда сессия этого аккаунта уже лежит в хранилище,
@@ -1620,10 +1636,15 @@ var ItdAccounts = class ItdAccounts {
1620
1636
  try {
1621
1637
  client = createManagedClient(this.#mergeOptions(options, storageControl.storage), this.#queues ? { queues: this.#queues } : {});
1622
1638
  for (const plugin of this.#plugins) client.use(plugin);
1639
+ for (const feature of this.#features) {
1640
+ const manifest = feature.create();
1641
+ if (feature.key === void 0) client.install(manifest);
1642
+ else client.withFeature(feature.key, manifest);
1643
+ }
1623
1644
  } catch (error) {
1624
1645
  storageControl.revoke();
1625
1646
  if (client) client.dispose().catch((cleanupError) => {
1626
- this.#reportPluginCleanup("неудачного добавления аккаунта", cleanupError);
1647
+ this.#reportCleanup("неудачного добавления аккаунта", cleanupError);
1627
1648
  });
1628
1649
  throw error;
1629
1650
  }
@@ -1747,7 +1768,7 @@ var ItdAccounts = class ItdAccounts {
1747
1768
  }
1748
1769
  } catch (error) {
1749
1770
  for (const client of installed.reverse()) client.unuse(plugin.name).catch((cleanupError) => {
1750
- this.#reportPluginCleanup(`отката плагина «${plugin.name}»`, cleanupError);
1771
+ this.#reportCleanup(`отката плагина «${plugin.name}»`, cleanupError);
1751
1772
  });
1752
1773
  throw error;
1753
1774
  }
@@ -1863,6 +1884,7 @@ var ItdAccounts = class ItdAccounts {
1863
1884
  Promise.resolve().then(() => this.#queues?.clear())
1864
1885
  ]);
1865
1886
  this.#plugins.splice(0);
1887
+ this.#features.splice(0);
1866
1888
  this.#removingPlugins.clear();
1867
1889
  const errors = results.filter((result) => result.status === "rejected").map((result) => result.reason);
1868
1890
  if (errors.length > 0) throw new AggregateError(errors, "Не удалось освободить аккаунты");
@@ -1872,11 +1894,7 @@ var ItdAccounts = class ItdAccounts {
1872
1894
  return this.dispose();
1873
1895
  }
1874
1896
  static {
1875
- if (typeof Symbol.asyncDispose !== "symbol") {
1876
- const prototype = ItdAccounts.prototype;
1877
- prototype[Symbol.for("Symbol.asyncDispose")] = prototype.undefined;
1878
- delete prototype.undefined;
1879
- }
1897
+ require_url.installAsyncDisposeFallback(ItdAccounts);
1880
1898
  }
1881
1899
  /**
1882
1900
  * Собирает опции клиента: общие, поверх них — аккаунтные, и обязательно свой срез
@@ -1901,9 +1919,9 @@ var ItdAccounts = class ItdAccounts {
1901
1919
  storage
1902
1920
  };
1903
1921
  }
1904
- /** Не теряет ошибку фонового teardown, который синхронный API не может await-нуть. */
1905
- #reportPluginCleanup(scope, error) {
1906
- const message = `Не удалось завершить teardown после ${scope}`;
1922
+ /** Не теряет ошибку фонового освобождения ресурсов, которого синхронный API не ждёт. */
1923
+ #reportCleanup(scope, error) {
1924
+ const message = `Не удалось освободить ресурсы после ${scope}`;
1907
1925
  if (this.#logger) this.#logger.error(message, error);
1908
1926
  else console.error(`[itd-api] ${message}`, error);
1909
1927
  }
@@ -1943,6 +1961,10 @@ exports.BUCKET_LIMITS = require_url.BUCKET_LIMITS;
1943
1961
  exports.CommentSort = require_url.CommentSort;
1944
1962
  exports.DEFAULT_BASE_URL = require_url.DEFAULT_BASE_URL;
1945
1963
  exports.DEFAULT_RATE_LIMIT_BUCKET = require_url.DEFAULT_RATE_LIMIT_BUCKET;
1964
+ exports.EventChannel = require_events.EventChannel;
1965
+ exports.EventChannelStatus = require_url.EventChannelStatus;
1966
+ exports.EventComposer = require_events.EventComposer;
1967
+ exports.EventRouter = require_events.EventRouter;
1946
1968
  exports.FeedTab = require_url.FeedTab;
1947
1969
  exports.FileTransferMode = require_options.FileTransferMode;
1948
1970
  exports.IMAGE_MIME_TYPES = require_render.IMAGE_MIME_TYPES;
@@ -1966,7 +1988,6 @@ exports.ItdNetworkError = require_errors.ItdNetworkError;
1966
1988
  exports.ItdNotFoundError = require_errors.ItdNotFoundError;
1967
1989
  exports.ItdPhoneVerificationError = require_errors.ItdPhoneVerificationError;
1968
1990
  exports.ItdRateLimitError = require_errors.ItdRateLimitError;
1969
- exports.ItdRealtime = require_websocket.ItdRealtime;
1970
1991
  exports.ItdServerError = require_errors.ItdServerError;
1971
1992
  exports.ItdStateError = require_errors.ItdStateError;
1972
1993
  exports.ItdTimeoutError = require_errors.ItdTimeoutError;
@@ -1976,33 +1997,32 @@ exports.LikesVisibility = require_url.LikesVisibility;
1976
1997
  exports.MemoryKeyValueStore = require_storage.MemoryKeyValueStore;
1977
1998
  exports.MemoryMultiTokenStorage = require_multi_storage.MemoryMultiTokenStorage;
1978
1999
  exports.MemoryTokenStorage = require_storage.MemoryTokenStorage;
2000
+ exports.NotificationEvents = require_events.NotificationEvents;
2001
+ exports.NotificationEventsClient = require_events.NotificationEventsClient;
2002
+ exports.NotificationEventsTransport = require_events.NotificationEventsTransport;
1979
2003
  exports.NotificationType = require_url.NotificationType;
2004
+ exports.NotificationUpdateOrigin = require_events.NotificationUpdateOrigin;
2005
+ exports.NotificationUpdateType = require_events.NotificationUpdateType;
1980
2006
  exports.OPERATIONS = require_url.OPERATIONS;
1981
2007
  exports.PaginationMode = require_render.PaginationMode;
1982
2008
  exports.Paginator = require_render.Paginator;
1983
2009
  exports.RateLimitPacing = require_url.RateLimitPacing;
1984
- exports.RealtimeComposer = require_websocket.RealtimeComposer;
1985
- exports.RealtimeRouter = require_websocket.RealtimeRouter;
1986
- exports.RealtimeStatus = require_url.RealtimeStatus;
1987
- exports.RealtimeTransportKind = require_websocket.RealtimeTransportKind;
1988
- exports.RealtimeUpdateOrigin = require_websocket.RealtimeUpdateOrigin;
1989
- exports.RealtimeUpdateType = require_websocket.RealtimeUpdateType;
1990
2010
  exports.ReportReason = require_url.ReportReason;
1991
2011
  exports.ReportTargetType = require_url.ReportTargetType;
1992
2012
  exports.RetrySafety = require_url.RetrySafety;
1993
- exports.RuntimeMode = require_url.RuntimeMode;
2013
+ exports.RuntimeMode = require_redact.RuntimeMode;
1994
2014
  exports.STATUS_SERVICE = require_url.STATUS_SERVICE;
1995
2015
  exports.ServiceState = require_url.ServiceState;
1996
2016
  exports.SignInStatus = SignInStatus;
1997
2017
  exports.SpanRenderFormat = require_render.SpanRenderFormat;
1998
2018
  exports.SpanType = require_url.SpanType;
1999
2019
  exports.TURNSTILE_SITE_KEY = TURNSTILE_SITE_KEY;
2000
- exports.UnauthorizedStreamError = require_websocket.UnauthorizedStreamError;
2020
+ exports.UnauthorizedStreamError = require_events.UnauthorizedStreamError;
2001
2021
  exports.VIDEO_MIME_TYPES = require_render.VIDEO_MIME_TYPES;
2002
2022
  exports.ViewReason = require_url.ViewReason;
2003
2023
  exports.ViewSource = require_url.ViewSource;
2004
2024
  exports.WallAccess = require_url.WallAccess;
2005
- exports.WebSocketTransport = require_websocket.WebSocketTransport;
2025
+ exports.WebSocketTransport = require_events.WebSocketTransport;
2006
2026
  exports.autoSpans = require_render.autoSpans;
2007
2027
  exports.canonicalNotificationType = require_url.canonicalNotificationType;
2008
2028
  exports.comment = require_render.comment;
@@ -2010,6 +2030,7 @@ exports.createAccounts = createAccounts;
2010
2030
  exports.createClient = createClient;
2011
2031
  exports.createKeyValueStore = require_storage.createKeyValueStore;
2012
2032
  exports.createMultiTokenStorage = require_multi_storage.createMultiTokenStorage;
2033
+ exports.createNotificationEventsClient = require_events.createNotificationEventsClient;
2013
2034
  exports.createRecordKeyValueStore = require_storage.createRecordKeyValueStore;
2014
2035
  exports.createTokenStorage = require_storage.createTokenStorage;
2015
2036
  exports.formatNotificationText = require_url.formatNotificationText;
@@ -2045,7 +2066,7 @@ exports.post = require_render.post;
2045
2066
  exports.renderSpans = require_render.renderSpans;
2046
2067
  exports.report = require_render.report;
2047
2068
  exports.resolveNotificationUrl = require_url.resolveNotificationUrl;
2048
- exports.runRealtimeMiddleware = require_websocket.runRealtimeMiddleware;
2069
+ exports.runEventMiddleware = require_events.runEventMiddleware;
2049
2070
  exports.scopedTokenStorage = require_multi_storage.scopedTokenStorage;
2050
2071
  exports.statusDays = require_render.statusDays;
2051
2072
  exports.systemClock = require_url.systemClock;