itd-api 0.7.2 → 0.9.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 (104) hide show
  1. package/README.md +72 -27
  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 +234 -200
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +70 -64
  9. package/dist/index.d.ts +70 -64
  10. package/dist/index.js +202 -179
  11. package/dist/index.js.map +1 -1
  12. package/dist/node/index.cjs +6 -5
  13. package/dist/node/index.cjs.map +1 -1
  14. package/dist/node/index.d.cts +2 -2
  15. package/dist/node/index.d.ts +2 -2
  16. package/dist/node/index.js +5 -4
  17. package/dist/node/index.js.map +1 -1
  18. package/dist/rest/index.cjs +32 -26
  19. package/dist/rest/index.cjs.map +1 -1
  20. package/dist/rest/index.d.cts +9 -7
  21. package/dist/rest/index.d.ts +9 -7
  22. package/dist/rest/index.js +19 -21
  23. package/dist/rest/index.js.map +1 -1
  24. package/dist/shared/{errors-DfU8M5eS.cjs → errors-BmP3TKoW.cjs} +3 -3
  25. package/dist/shared/{errors-DfU8M5eS.cjs.map → errors-BmP3TKoW.cjs.map} +1 -1
  26. package/dist/shared/{errors-Bhrd2fJd.js → errors-GI10kZxk.js} +3 -3
  27. package/dist/shared/{errors-Bhrd2fJd.js.map → errors-GI10kZxk.js.map} +1 -1
  28. package/dist/shared/{websocket-BLR8eVJV.js → events-C5wnTXPT.js} +770 -490
  29. package/dist/shared/events-C5wnTXPT.js.map +1 -0
  30. package/dist/shared/events-CqtkP65d.d.ts +698 -0
  31. package/dist/shared/events-DGAWlCaI.d.cts +698 -0
  32. package/dist/shared/{websocket-C_eI4H2o.cjs → events-FZfnEez0.cjs} +834 -518
  33. package/dist/shared/events-FZfnEez0.cjs.map +1 -0
  34. package/dist/shared/{storage-BPJR_k4-.cjs → key-value-store-B5GYVEYZ.cjs} +2 -86
  35. package/dist/shared/key-value-store-B5GYVEYZ.cjs.map +1 -0
  36. package/dist/shared/{storage-D86edNCB.js → key-value-store-Bt2PSMxY.js} +3 -69
  37. package/dist/shared/key-value-store-Bt2PSMxY.js.map +1 -0
  38. package/dist/shared/key-value-store-COZaNHZS.d.cts +69 -0
  39. package/dist/shared/key-value-store-COZaNHZS.d.ts +69 -0
  40. package/dist/shared/{multi-storage-DccjD7Ww.d.ts → multi-storage-BEL7tcKn.d.cts} +3 -2
  41. package/dist/shared/{multi-storage--yTEqiod.cjs → multi-storage-CDKLa956.cjs} +11 -10
  42. package/dist/shared/{multi-storage--yTEqiod.cjs.map → multi-storage-CDKLa956.cjs.map} +1 -1
  43. package/dist/shared/{multi-storage-CjAPB5Kq.d.cts → multi-storage-LkljOSzA.d.ts} +3 -2
  44. package/dist/shared/{multi-storage-CkvTUC5m.js → multi-storage-SoW05uzO.js} +5 -4
  45. package/dist/shared/{multi-storage-CkvTUC5m.js.map → multi-storage-SoW05uzO.js.map} +1 -1
  46. package/dist/shared/{options-Dg5N3r1V.cjs → options-DOJYtoti.cjs} +8 -6
  47. package/dist/shared/options-DOJYtoti.cjs.map +1 -0
  48. package/dist/shared/{options-DtATYdLr.js → options-DhgGg7Ms.js} +8 -6
  49. package/dist/shared/options-DhgGg7Ms.js.map +1 -0
  50. package/dist/shared/{cookies-DZwFq6kr.cjs → redact-BP00URmQ.cjs} +312 -2
  51. package/dist/shared/redact-BP00URmQ.cjs.map +1 -0
  52. package/dist/shared/{cookies-tX2sNwxb.js → redact-Ba5iSVYZ.js} +235 -3
  53. package/dist/shared/redact-Ba5iSVYZ.js.map +1 -0
  54. package/dist/shared/{render-CgwKdOzu.d.ts → render-B4qis7Sb.d.ts} +775 -313
  55. package/dist/shared/{render-DO0F5YSm.d.cts → render-DDwy2Ame.d.cts} +775 -313
  56. package/dist/shared/{render-mcuELiYi.cjs → render-Dqi8Owqk.cjs} +1464 -662
  57. package/dist/shared/render-Dqi8Owqk.cjs.map +1 -0
  58. package/dist/shared/{render-C6HRPs10.js → render-hiWFh2s4.js} +1366 -618
  59. package/dist/shared/render-hiWFh2s4.js.map +1 -0
  60. package/dist/shared/storage-BQrtKon9.d.cts +86 -0
  61. package/dist/shared/storage-CTRGT5wF.d.ts +86 -0
  62. package/dist/shared/storage-CfHKzVHf.js +71 -0
  63. package/dist/shared/storage-CfHKzVHf.js.map +1 -0
  64. package/dist/shared/storage-QNVxzpDB.cjs +88 -0
  65. package/dist/shared/storage-QNVxzpDB.cjs.map +1 -0
  66. package/dist/shared/{url-BaMCQpYH.cjs → url-Bsb3xE5U.cjs} +577 -466
  67. package/dist/shared/url-Bsb3xE5U.cjs.map +1 -0
  68. package/dist/shared/{url-IU0xN9wX.js → url-DP33mp3s.js} +508 -409
  69. package/dist/shared/url-DP33mp3s.js.map +1 -0
  70. package/dist/shared/{url-DTfZ2toq.d.ts → url-XBsMdAcv.d.cts} +1313 -1200
  71. package/dist/shared/{url-DTfZ2toq.d.cts → url-XBsMdAcv.d.ts} +1313 -1200
  72. package/dist/web/index.cjs +5 -4
  73. package/dist/web/index.cjs.map +1 -1
  74. package/dist/web/index.d.cts +1 -1
  75. package/dist/web/index.d.ts +1 -1
  76. package/dist/web/index.js +3 -2
  77. package/dist/web/index.js.map +1 -1
  78. package/package.json +16 -15
  79. package/dist/realtime/index.cjs +0 -165
  80. package/dist/realtime/index.cjs.map +0 -1
  81. package/dist/realtime/index.d.cts +0 -51
  82. package/dist/realtime/index.d.ts +0 -51
  83. package/dist/realtime/index.js +0 -120
  84. package/dist/realtime/index.js.map +0 -1
  85. package/dist/shared/auth-provider-CG8oCQ9F.cjs +0 -108
  86. package/dist/shared/auth-provider-CG8oCQ9F.cjs.map +0 -1
  87. package/dist/shared/auth-provider-mYqxsSVa.js +0 -91
  88. package/dist/shared/auth-provider-mYqxsSVa.js.map +0 -1
  89. package/dist/shared/cookies-DZwFq6kr.cjs.map +0 -1
  90. package/dist/shared/cookies-tX2sNwxb.js.map +0 -1
  91. package/dist/shared/options-Dg5N3r1V.cjs.map +0 -1
  92. package/dist/shared/options-DtATYdLr.js.map +0 -1
  93. package/dist/shared/render-C6HRPs10.js.map +0 -1
  94. package/dist/shared/render-mcuELiYi.cjs.map +0 -1
  95. package/dist/shared/storage-BPJR_k4-.cjs.map +0 -1
  96. package/dist/shared/storage-C_eICCep.d.cts +0 -152
  97. package/dist/shared/storage-C_eICCep.d.ts +0 -152
  98. package/dist/shared/storage-D86edNCB.js.map +0 -1
  99. package/dist/shared/url-BaMCQpYH.cjs.map +0 -1
  100. package/dist/shared/url-IU0xN9wX.js.map +0 -1
  101. package/dist/shared/websocket-BLR8eVJV.js.map +0 -1
  102. package/dist/shared/websocket-C_eI4H2o.cjs.map +0 -1
  103. package/dist/shared/websocket-DF7XIMiX.d.cts +0 -562
  104. package/dist/shared/websocket-DYKBr8HF.d.ts +0 -562
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_errors = require("../shared/errors-DfU8M5eS.cjs");
3
- const require_storage = require("../shared/storage-BPJR_k4-.cjs");
2
+ const require_errors = require("../shared/errors-BmP3TKoW.cjs");
3
+ const require_key_value_store = require("../shared/key-value-store-B5GYVEYZ.cjs");
4
+ const require_storage = require("../shared/storage-QNVxzpDB.cjs");
4
5
  //#region src/web.ts
5
6
  /**
6
7
  * `itd-api/web` — хранилища для браузера.
@@ -31,7 +32,7 @@ function getWebStorage(property) {
31
32
  }
32
33
  /** Общая реализация Web Storage; публичные классы ниже фиксируют его вид. */
33
34
  var WebStorageKeyValueStore = class {
34
- #fallback = new require_storage.MemoryKeyValueStore();
35
+ #fallback = new require_key_value_store.MemoryKeyValueStore();
35
36
  #storage;
36
37
  #property;
37
38
  constructor(property) {
@@ -88,7 +89,7 @@ var WebStorageKeyValueStore = class {
88
89
  }
89
90
  #degrade() {
90
91
  this.#storage = void 0;
91
- this.#fallback = new require_storage.MemoryKeyValueStore();
92
+ this.#fallback = new require_key_value_store.MemoryKeyValueStore();
92
93
  }
93
94
  };
94
95
  /** JSON key-value backend поверх браузерного `localStorage` с откатом в память. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["MemoryKeyValueStore","#property","#storage","#fallback","#degrade","ItdConfigError","#inner","createTokenStorage"],"sources":["../../src/web.ts"],"sourcesContent":["/**\n * `itd-api/web` — хранилища для браузера.\n *\n * Здесь лежит только то, что рассчитано на браузерное окружение. Клиент, аккаунты,\n * билдеры, типы и всё остальное берутся из `itd-api` — одинаково на всех платформах.\n *\n * Отдельная точка входа нужна не сборщику, а вам: браузерные хранилища при\n * недоступном Web Storage молча работают в памяти, и такое поведение стоит выбирать\n * осознанно, а не получать вместе с общим импортом.\n *\n * @example\n * ```ts\n * import { ItdClient } from 'itd-api';\n * import { LocalStorageTokenStorage } from 'itd-api/web';\n *\n * const itd = new ItdClient({ storage: new LocalStorageTokenStorage() });\n * ```\n *\n * @packageDocumentation\n */\n\nimport { ItdConfigError } from './core/errors.js';\nimport { MemoryKeyValueStore } from './core/key-value-store.js';\nimport { createTokenStorage, type ItdSession, type TokenStorage } from './session/storage.js';\n\ntype WebStorageProperty = 'localStorage' | 'sessionStorage';\n\nfunction getWebStorage(property: WebStorageProperty): Storage | undefined {\n try {\n return globalThis[property] ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Общая реализация Web Storage; публичные классы ниже фиксируют его вид. */\nclass WebStorageKeyValueStore<T> {\n #fallback = new MemoryKeyValueStore<T>();\n #storage: Storage | undefined;\n readonly #property: WebStorageProperty;\n\n constructor(property: WebStorageProperty) {\n this.#property = property;\n this.#storage = getWebStorage(property);\n }\n\n get(key: string): T | undefined {\n if (!this.#storage) return this.#fallback.get(key);\n let raw: string | null;\n try {\n raw = this.#storage.getItem(key);\n } catch {\n this.#degrade();\n return this.#fallback.get(key);\n }\n if (raw === null) return undefined;\n try {\n return JSON.parse(raw) as T;\n } catch (error) {\n throw new ItdConfigError(`Повреждён JSON в ${this.#property} по ключу «${key}»`, {\n cause: error,\n });\n }\n }\n\n set(key: string, value: T): void {\n if (this.#storage) {\n try {\n this.#storage.setItem(key, JSON.stringify(value));\n return;\n } catch {\n this.#degrade();\n }\n }\n this.#fallback.set(key, value);\n }\n\n delete(key: string): void {\n if (this.#storage) {\n try {\n this.#storage.removeItem(key);\n return;\n } catch {\n this.#degrade();\n }\n }\n this.#fallback.delete(key);\n }\n\n keys(prefix = ''): Iterable<string> | AsyncIterable<string> {\n if (!this.#storage) return this.#fallback.keys(prefix);\n try {\n const keys: string[] = [];\n for (let index = 0; index < this.#storage.length; index += 1) {\n const key = this.#storage.key(index);\n if (key?.startsWith(prefix)) keys.push(key);\n }\n return keys;\n } catch {\n this.#degrade();\n return this.#fallback.keys(prefix);\n }\n }\n\n #degrade(): void {\n this.#storage = undefined;\n this.#fallback = new MemoryKeyValueStore<T>();\n }\n}\n\n/** JSON key-value backend поверх браузерного `localStorage` с откатом в память. */\nexport class LocalStorageKeyValueStore<T> {\n readonly #inner = new WebStorageKeyValueStore<T>('localStorage');\n\n get(key: string): T | undefined {\n return this.#inner.get(key);\n }\n\n set(key: string, value: T): void {\n this.#inner.set(key, value);\n }\n\n delete(key: string): void {\n this.#inner.delete(key);\n }\n\n keys(prefix = ''): Iterable<string> | AsyncIterable<string> {\n return this.#inner.keys(prefix);\n }\n}\n\n/** JSON key-value backend поверх браузерного `sessionStorage` с откатом в память. */\nexport class SessionStorageKeyValueStore<T> {\n readonly #inner = new WebStorageKeyValueStore<T>('sessionStorage');\n\n get(key: string): T | undefined {\n return this.#inner.get(key);\n }\n\n set(key: string, value: T): void {\n this.#inner.set(key, value);\n }\n\n delete(key: string): void {\n this.#inner.delete(key);\n }\n\n keys(prefix = ''): Iterable<string> | AsyncIterable<string> {\n return this.#inner.keys(prefix);\n }\n}\n\n/**\n * Хранилище поверх `localStorage` браузера.\n *\n * Если `localStorage` недоступен (приватный режим, серверный рендеринг), молча работает\n * как хранилище в памяти — библиотека не должна падать из-за настроек браузера. Сессия\n * в этом случае теряется при перезагрузке страницы; когда это неприемлемо, проверьте\n * доступность сами или возьмите своё хранилище через `createTokenStorage`.\n *\n * Помните, что `localStorage` доступен любому скрипту на странице: не используйте его,\n * если для вашего приложения это неприемлемый риск.\n *\n * Повреждённый JSON считается ошибкой, а не отсутствующей сессией. После ошибки доступа,\n * записи или удаления хранилище переключается на память до конца\n * своего жизненного цикла.\n */\nexport class LocalStorageTokenStorage implements TokenStorage {\n readonly #inner: TokenStorage;\n\n /** @param key ключ в `localStorage`. По умолчанию `itd-api:session`. */\n constructor(key = 'itd-api:session') {\n this.#inner = createTokenStorage(new LocalStorageKeyValueStore<ItdSession>(), { key });\n }\n\n get(): ItdSession | null {\n return this.#inner.get() as ItdSession | null;\n }\n\n set(session: ItdSession): void {\n void this.#inner.set(session);\n }\n\n clear(): void {\n void this.#inner.clear();\n }\n}\n\n/**\n * Хранилище сессии поверх браузерного `sessionStorage`.\n *\n * Данные переживают перезагрузку страницы, но существуют только в пределах текущей\n * browser page session. Если `sessionStorage` недоступен, экземпляр молча работает\n * в памяти; после ошибки доступа, записи или удаления он также остаётся в памяти до конца\n * своего жизненного цикла.\n * Повреждённый JSON считается ошибкой, а не отсутствующей сессией.\n *\n * Как и `localStorage`, это хранилище доступно скриптам страницы и не защищает сессию\n * от XSS. Выбирайте его ради более короткого срока жизни, а не ради изоляции секрета.\n */\nexport class SessionStorageTokenStorage implements TokenStorage {\n readonly #inner: TokenStorage;\n\n /** @param key ключ в `sessionStorage`. По умолчанию `itd-api:session`. */\n constructor(key = 'itd-api:session') {\n this.#inner = createTokenStorage(new SessionStorageKeyValueStore<ItdSession>(), { key });\n }\n\n get(): ItdSession | null {\n return this.#inner.get() as ItdSession | null;\n }\n\n set(session: ItdSession): void {\n void this.#inner.set(session);\n }\n\n clear(): void {\n void this.#inner.clear();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["MemoryKeyValueStore","#property","#storage","#fallback","#degrade","ItdConfigError","#inner","createTokenStorage"],"sources":["../../src/web.ts"],"sourcesContent":["/**\n * `itd-api/web` — хранилища для браузера.\n *\n * Здесь лежит только то, что рассчитано на браузерное окружение. Клиент, аккаунты,\n * билдеры, типы и всё остальное берутся из `itd-api` — одинаково на всех платформах.\n *\n * Отдельная точка входа нужна не сборщику, а вам: браузерные хранилища при\n * недоступном Web Storage молча работают в памяти, и такое поведение стоит выбирать\n * осознанно, а не получать вместе с общим импортом.\n *\n * @example\n * ```ts\n * import { ItdClient } from 'itd-api';\n * import { LocalStorageTokenStorage } from 'itd-api/web';\n *\n * const itd = new ItdClient({ storage: new LocalStorageTokenStorage() });\n * ```\n *\n * @packageDocumentation\n */\n\nimport { ItdConfigError } from './core/errors.js';\nimport { MemoryKeyValueStore } from './core/key-value-store.js';\nimport { createTokenStorage, type ItdSession, type TokenStorage } from './session/storage.js';\n\ntype WebStorageProperty = 'localStorage' | 'sessionStorage';\n\nfunction getWebStorage(property: WebStorageProperty): Storage | undefined {\n try {\n return globalThis[property] ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Общая реализация Web Storage; публичные классы ниже фиксируют его вид. */\nclass WebStorageKeyValueStore<T> {\n #fallback = new MemoryKeyValueStore<T>();\n #storage: Storage | undefined;\n readonly #property: WebStorageProperty;\n\n constructor(property: WebStorageProperty) {\n this.#property = property;\n this.#storage = getWebStorage(property);\n }\n\n get(key: string): T | undefined {\n if (!this.#storage) return this.#fallback.get(key);\n let raw: string | null;\n try {\n raw = this.#storage.getItem(key);\n } catch {\n this.#degrade();\n return this.#fallback.get(key);\n }\n if (raw === null) return undefined;\n try {\n return JSON.parse(raw) as T;\n } catch (error) {\n throw new ItdConfigError(`Повреждён JSON в ${this.#property} по ключу «${key}»`, {\n cause: error,\n });\n }\n }\n\n set(key: string, value: T): void {\n if (this.#storage) {\n try {\n this.#storage.setItem(key, JSON.stringify(value));\n return;\n } catch {\n this.#degrade();\n }\n }\n this.#fallback.set(key, value);\n }\n\n delete(key: string): void {\n if (this.#storage) {\n try {\n this.#storage.removeItem(key);\n return;\n } catch {\n this.#degrade();\n }\n }\n this.#fallback.delete(key);\n }\n\n keys(prefix = ''): Iterable<string> | AsyncIterable<string> {\n if (!this.#storage) return this.#fallback.keys(prefix);\n try {\n const keys: string[] = [];\n for (let index = 0; index < this.#storage.length; index += 1) {\n const key = this.#storage.key(index);\n if (key?.startsWith(prefix)) keys.push(key);\n }\n return keys;\n } catch {\n this.#degrade();\n return this.#fallback.keys(prefix);\n }\n }\n\n #degrade(): void {\n this.#storage = undefined;\n this.#fallback = new MemoryKeyValueStore<T>();\n }\n}\n\n/** JSON key-value backend поверх браузерного `localStorage` с откатом в память. */\nexport class LocalStorageKeyValueStore<T> {\n readonly #inner = new WebStorageKeyValueStore<T>('localStorage');\n\n get(key: string): T | undefined {\n return this.#inner.get(key);\n }\n\n set(key: string, value: T): void {\n this.#inner.set(key, value);\n }\n\n delete(key: string): void {\n this.#inner.delete(key);\n }\n\n keys(prefix = ''): Iterable<string> | AsyncIterable<string> {\n return this.#inner.keys(prefix);\n }\n}\n\n/** JSON key-value backend поверх браузерного `sessionStorage` с откатом в память. */\nexport class SessionStorageKeyValueStore<T> {\n readonly #inner = new WebStorageKeyValueStore<T>('sessionStorage');\n\n get(key: string): T | undefined {\n return this.#inner.get(key);\n }\n\n set(key: string, value: T): void {\n this.#inner.set(key, value);\n }\n\n delete(key: string): void {\n this.#inner.delete(key);\n }\n\n keys(prefix = ''): Iterable<string> | AsyncIterable<string> {\n return this.#inner.keys(prefix);\n }\n}\n\n/**\n * Хранилище поверх `localStorage` браузера.\n *\n * Если `localStorage` недоступен (приватный режим, серверный рендеринг), молча работает\n * как хранилище в памяти — библиотека не должна падать из-за настроек браузера. Сессия\n * в этом случае теряется при перезагрузке страницы; когда это неприемлемо, проверьте\n * доступность сами или возьмите своё хранилище через `createTokenStorage`.\n *\n * Помните, что `localStorage` доступен любому скрипту на странице: не используйте его,\n * если для вашего приложения это неприемлемый риск.\n *\n * Повреждённый JSON считается ошибкой, а не отсутствующей сессией. После ошибки доступа,\n * записи или удаления хранилище переключается на память до конца\n * своего жизненного цикла.\n */\nexport class LocalStorageTokenStorage implements TokenStorage {\n readonly #inner: TokenStorage;\n\n /** @param key ключ в `localStorage`. По умолчанию `itd-api:session`. */\n constructor(key = 'itd-api:session') {\n this.#inner = createTokenStorage(new LocalStorageKeyValueStore<ItdSession>(), { key });\n }\n\n get(): ItdSession | null {\n return this.#inner.get() as ItdSession | null;\n }\n\n set(session: ItdSession): void {\n void this.#inner.set(session);\n }\n\n clear(): void {\n void this.#inner.clear();\n }\n}\n\n/**\n * Хранилище сессии поверх браузерного `sessionStorage`.\n *\n * Данные переживают перезагрузку страницы, но существуют только в пределах текущей\n * browser page session. Если `sessionStorage` недоступен, экземпляр молча работает\n * в памяти; после ошибки доступа, записи или удаления он также остаётся в памяти до конца\n * своего жизненного цикла.\n * Повреждённый JSON считается ошибкой, а не отсутствующей сессией.\n *\n * Как и `localStorage`, это хранилище доступно скриптам страницы и не защищает сессию\n * от XSS. Выбирайте его ради более короткого срока жизни, а не ради изоляции секрета.\n */\nexport class SessionStorageTokenStorage implements TokenStorage {\n readonly #inner: TokenStorage;\n\n /** @param key ключ в `sessionStorage`. По умолчанию `itd-api:session`. */\n constructor(key = 'itd-api:session') {\n this.#inner = createTokenStorage(new SessionStorageKeyValueStore<ItdSession>(), { key });\n }\n\n get(): ItdSession | null {\n return this.#inner.get() as ItdSession | null;\n }\n\n set(session: ItdSession): void {\n void this.#inner.set(session);\n }\n\n clear(): void {\n void this.#inner.clear();\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { r as TokenStorage, t as ItdSession } from "../shared/storage-C_eICCep.cjs";
1
+ import { r as TokenStorage, t as ItdSession } from "../shared/storage-BQrtKon9.cjs";
2
2
  //#region src/web.d.ts
3
3
  /** JSON key-value backend поверх браузерного `localStorage` с откатом в память. */
4
4
  declare class LocalStorageKeyValueStore<T> {
@@ -1,4 +1,4 @@
1
- import { r as TokenStorage, t as ItdSession } from "../shared/storage-C_eICCep.js";
1
+ import { r as TokenStorage, t as ItdSession } from "../shared/storage-CTRGT5wF.js";
2
2
  //#region src/web.d.ts
3
3
  /** JSON key-value backend поверх браузерного `localStorage` с откатом в память. */
4
4
  declare class LocalStorageKeyValueStore<T> {
package/dist/web/index.js CHANGED
@@ -1,5 +1,6 @@
1
- import { a as ItdConfigError } from "../shared/errors-Bhrd2fJd.js";
2
- import { i as MemoryKeyValueStore, r as createTokenStorage } from "../shared/storage-D86edNCB.js";
1
+ import { a as ItdConfigError } from "../shared/errors-GI10kZxk.js";
2
+ import { t as MemoryKeyValueStore } from "../shared/key-value-store-Bt2PSMxY.js";
3
+ import { r as createTokenStorage } from "../shared/storage-CfHKzVHf.js";
3
4
  //#region src/web.ts
4
5
  /**
5
6
  * `itd-api/web` — хранилища для браузера.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["#property","#storage","#fallback","#degrade","#inner"],"sources":["../../src/web.ts"],"sourcesContent":["/**\n * `itd-api/web` — хранилища для браузера.\n *\n * Здесь лежит только то, что рассчитано на браузерное окружение. Клиент, аккаунты,\n * билдеры, типы и всё остальное берутся из `itd-api` — одинаково на всех платформах.\n *\n * Отдельная точка входа нужна не сборщику, а вам: браузерные хранилища при\n * недоступном Web Storage молча работают в памяти, и такое поведение стоит выбирать\n * осознанно, а не получать вместе с общим импортом.\n *\n * @example\n * ```ts\n * import { ItdClient } from 'itd-api';\n * import { LocalStorageTokenStorage } from 'itd-api/web';\n *\n * const itd = new ItdClient({ storage: new LocalStorageTokenStorage() });\n * ```\n *\n * @packageDocumentation\n */\n\nimport { ItdConfigError } from './core/errors.js';\nimport { MemoryKeyValueStore } from './core/key-value-store.js';\nimport { createTokenStorage, type ItdSession, type TokenStorage } from './session/storage.js';\n\ntype WebStorageProperty = 'localStorage' | 'sessionStorage';\n\nfunction getWebStorage(property: WebStorageProperty): Storage | undefined {\n try {\n return globalThis[property] ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Общая реализация Web Storage; публичные классы ниже фиксируют его вид. */\nclass WebStorageKeyValueStore<T> {\n #fallback = new MemoryKeyValueStore<T>();\n #storage: Storage | undefined;\n readonly #property: WebStorageProperty;\n\n constructor(property: WebStorageProperty) {\n this.#property = property;\n this.#storage = getWebStorage(property);\n }\n\n get(key: string): T | undefined {\n if (!this.#storage) return this.#fallback.get(key);\n let raw: string | null;\n try {\n raw = this.#storage.getItem(key);\n } catch {\n this.#degrade();\n return this.#fallback.get(key);\n }\n if (raw === null) return undefined;\n try {\n return JSON.parse(raw) as T;\n } catch (error) {\n throw new ItdConfigError(`Повреждён JSON в ${this.#property} по ключу «${key}»`, {\n cause: error,\n });\n }\n }\n\n set(key: string, value: T): void {\n if (this.#storage) {\n try {\n this.#storage.setItem(key, JSON.stringify(value));\n return;\n } catch {\n this.#degrade();\n }\n }\n this.#fallback.set(key, value);\n }\n\n delete(key: string): void {\n if (this.#storage) {\n try {\n this.#storage.removeItem(key);\n return;\n } catch {\n this.#degrade();\n }\n }\n this.#fallback.delete(key);\n }\n\n keys(prefix = ''): Iterable<string> | AsyncIterable<string> {\n if (!this.#storage) return this.#fallback.keys(prefix);\n try {\n const keys: string[] = [];\n for (let index = 0; index < this.#storage.length; index += 1) {\n const key = this.#storage.key(index);\n if (key?.startsWith(prefix)) keys.push(key);\n }\n return keys;\n } catch {\n this.#degrade();\n return this.#fallback.keys(prefix);\n }\n }\n\n #degrade(): void {\n this.#storage = undefined;\n this.#fallback = new MemoryKeyValueStore<T>();\n }\n}\n\n/** JSON key-value backend поверх браузерного `localStorage` с откатом в память. */\nexport class LocalStorageKeyValueStore<T> {\n readonly #inner = new WebStorageKeyValueStore<T>('localStorage');\n\n get(key: string): T | undefined {\n return this.#inner.get(key);\n }\n\n set(key: string, value: T): void {\n this.#inner.set(key, value);\n }\n\n delete(key: string): void {\n this.#inner.delete(key);\n }\n\n keys(prefix = ''): Iterable<string> | AsyncIterable<string> {\n return this.#inner.keys(prefix);\n }\n}\n\n/** JSON key-value backend поверх браузерного `sessionStorage` с откатом в память. */\nexport class SessionStorageKeyValueStore<T> {\n readonly #inner = new WebStorageKeyValueStore<T>('sessionStorage');\n\n get(key: string): T | undefined {\n return this.#inner.get(key);\n }\n\n set(key: string, value: T): void {\n this.#inner.set(key, value);\n }\n\n delete(key: string): void {\n this.#inner.delete(key);\n }\n\n keys(prefix = ''): Iterable<string> | AsyncIterable<string> {\n return this.#inner.keys(prefix);\n }\n}\n\n/**\n * Хранилище поверх `localStorage` браузера.\n *\n * Если `localStorage` недоступен (приватный режим, серверный рендеринг), молча работает\n * как хранилище в памяти — библиотека не должна падать из-за настроек браузера. Сессия\n * в этом случае теряется при перезагрузке страницы; когда это неприемлемо, проверьте\n * доступность сами или возьмите своё хранилище через `createTokenStorage`.\n *\n * Помните, что `localStorage` доступен любому скрипту на странице: не используйте его,\n * если для вашего приложения это неприемлемый риск.\n *\n * Повреждённый JSON считается ошибкой, а не отсутствующей сессией. После ошибки доступа,\n * записи или удаления хранилище переключается на память до конца\n * своего жизненного цикла.\n */\nexport class LocalStorageTokenStorage implements TokenStorage {\n readonly #inner: TokenStorage;\n\n /** @param key ключ в `localStorage`. По умолчанию `itd-api:session`. */\n constructor(key = 'itd-api:session') {\n this.#inner = createTokenStorage(new LocalStorageKeyValueStore<ItdSession>(), { key });\n }\n\n get(): ItdSession | null {\n return this.#inner.get() as ItdSession | null;\n }\n\n set(session: ItdSession): void {\n void this.#inner.set(session);\n }\n\n clear(): void {\n void this.#inner.clear();\n }\n}\n\n/**\n * Хранилище сессии поверх браузерного `sessionStorage`.\n *\n * Данные переживают перезагрузку страницы, но существуют только в пределах текущей\n * browser page session. Если `sessionStorage` недоступен, экземпляр молча работает\n * в памяти; после ошибки доступа, записи или удаления он также остаётся в памяти до конца\n * своего жизненного цикла.\n * Повреждённый JSON считается ошибкой, а не отсутствующей сессией.\n *\n * Как и `localStorage`, это хранилище доступно скриптам страницы и не защищает сессию\n * от XSS. Выбирайте его ради более короткого срока жизни, а не ради изоляции секрета.\n */\nexport class SessionStorageTokenStorage implements TokenStorage {\n readonly #inner: TokenStorage;\n\n /** @param key ключ в `sessionStorage`. По умолчанию `itd-api:session`. */\n constructor(key = 'itd-api:session') {\n this.#inner = createTokenStorage(new SessionStorageKeyValueStore<ItdSession>(), { key });\n }\n\n get(): ItdSession | null {\n return this.#inner.get() as ItdSession | null;\n }\n\n set(session: ItdSession): void {\n void this.#inner.set(session);\n }\n\n clear(): void {\n void this.#inner.clear();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["#property","#storage","#fallback","#degrade","#inner"],"sources":["../../src/web.ts"],"sourcesContent":["/**\n * `itd-api/web` — хранилища для браузера.\n *\n * Здесь лежит только то, что рассчитано на браузерное окружение. Клиент, аккаунты,\n * билдеры, типы и всё остальное берутся из `itd-api` — одинаково на всех платформах.\n *\n * Отдельная точка входа нужна не сборщику, а вам: браузерные хранилища при\n * недоступном Web Storage молча работают в памяти, и такое поведение стоит выбирать\n * осознанно, а не получать вместе с общим импортом.\n *\n * @example\n * ```ts\n * import { ItdClient } from 'itd-api';\n * import { LocalStorageTokenStorage } from 'itd-api/web';\n *\n * const itd = new ItdClient({ storage: new LocalStorageTokenStorage() });\n * ```\n *\n * @packageDocumentation\n */\n\nimport { ItdConfigError } from './core/errors.js';\nimport { MemoryKeyValueStore } from './core/key-value-store.js';\nimport { createTokenStorage, type ItdSession, type TokenStorage } from './session/storage.js';\n\ntype WebStorageProperty = 'localStorage' | 'sessionStorage';\n\nfunction getWebStorage(property: WebStorageProperty): Storage | undefined {\n try {\n return globalThis[property] ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Общая реализация Web Storage; публичные классы ниже фиксируют его вид. */\nclass WebStorageKeyValueStore<T> {\n #fallback = new MemoryKeyValueStore<T>();\n #storage: Storage | undefined;\n readonly #property: WebStorageProperty;\n\n constructor(property: WebStorageProperty) {\n this.#property = property;\n this.#storage = getWebStorage(property);\n }\n\n get(key: string): T | undefined {\n if (!this.#storage) return this.#fallback.get(key);\n let raw: string | null;\n try {\n raw = this.#storage.getItem(key);\n } catch {\n this.#degrade();\n return this.#fallback.get(key);\n }\n if (raw === null) return undefined;\n try {\n return JSON.parse(raw) as T;\n } catch (error) {\n throw new ItdConfigError(`Повреждён JSON в ${this.#property} по ключу «${key}»`, {\n cause: error,\n });\n }\n }\n\n set(key: string, value: T): void {\n if (this.#storage) {\n try {\n this.#storage.setItem(key, JSON.stringify(value));\n return;\n } catch {\n this.#degrade();\n }\n }\n this.#fallback.set(key, value);\n }\n\n delete(key: string): void {\n if (this.#storage) {\n try {\n this.#storage.removeItem(key);\n return;\n } catch {\n this.#degrade();\n }\n }\n this.#fallback.delete(key);\n }\n\n keys(prefix = ''): Iterable<string> | AsyncIterable<string> {\n if (!this.#storage) return this.#fallback.keys(prefix);\n try {\n const keys: string[] = [];\n for (let index = 0; index < this.#storage.length; index += 1) {\n const key = this.#storage.key(index);\n if (key?.startsWith(prefix)) keys.push(key);\n }\n return keys;\n } catch {\n this.#degrade();\n return this.#fallback.keys(prefix);\n }\n }\n\n #degrade(): void {\n this.#storage = undefined;\n this.#fallback = new MemoryKeyValueStore<T>();\n }\n}\n\n/** JSON key-value backend поверх браузерного `localStorage` с откатом в память. */\nexport class LocalStorageKeyValueStore<T> {\n readonly #inner = new WebStorageKeyValueStore<T>('localStorage');\n\n get(key: string): T | undefined {\n return this.#inner.get(key);\n }\n\n set(key: string, value: T): void {\n this.#inner.set(key, value);\n }\n\n delete(key: string): void {\n this.#inner.delete(key);\n }\n\n keys(prefix = ''): Iterable<string> | AsyncIterable<string> {\n return this.#inner.keys(prefix);\n }\n}\n\n/** JSON key-value backend поверх браузерного `sessionStorage` с откатом в память. */\nexport class SessionStorageKeyValueStore<T> {\n readonly #inner = new WebStorageKeyValueStore<T>('sessionStorage');\n\n get(key: string): T | undefined {\n return this.#inner.get(key);\n }\n\n set(key: string, value: T): void {\n this.#inner.set(key, value);\n }\n\n delete(key: string): void {\n this.#inner.delete(key);\n }\n\n keys(prefix = ''): Iterable<string> | AsyncIterable<string> {\n return this.#inner.keys(prefix);\n }\n}\n\n/**\n * Хранилище поверх `localStorage` браузера.\n *\n * Если `localStorage` недоступен (приватный режим, серверный рендеринг), молча работает\n * как хранилище в памяти — библиотека не должна падать из-за настроек браузера. Сессия\n * в этом случае теряется при перезагрузке страницы; когда это неприемлемо, проверьте\n * доступность сами или возьмите своё хранилище через `createTokenStorage`.\n *\n * Помните, что `localStorage` доступен любому скрипту на странице: не используйте его,\n * если для вашего приложения это неприемлемый риск.\n *\n * Повреждённый JSON считается ошибкой, а не отсутствующей сессией. После ошибки доступа,\n * записи или удаления хранилище переключается на память до конца\n * своего жизненного цикла.\n */\nexport class LocalStorageTokenStorage implements TokenStorage {\n readonly #inner: TokenStorage;\n\n /** @param key ключ в `localStorage`. По умолчанию `itd-api:session`. */\n constructor(key = 'itd-api:session') {\n this.#inner = createTokenStorage(new LocalStorageKeyValueStore<ItdSession>(), { key });\n }\n\n get(): ItdSession | null {\n return this.#inner.get() as ItdSession | null;\n }\n\n set(session: ItdSession): void {\n void this.#inner.set(session);\n }\n\n clear(): void {\n void this.#inner.clear();\n }\n}\n\n/**\n * Хранилище сессии поверх браузерного `sessionStorage`.\n *\n * Данные переживают перезагрузку страницы, но существуют только в пределах текущей\n * browser page session. Если `sessionStorage` недоступен, экземпляр молча работает\n * в памяти; после ошибки доступа, записи или удаления он также остаётся в памяти до конца\n * своего жизненного цикла.\n * Повреждённый JSON считается ошибкой, а не отсутствующей сессией.\n *\n * Как и `localStorage`, это хранилище доступно скриптам страницы и не защищает сессию\n * от XSS. Выбирайте его ради более короткого срока жизни, а не ради изоляции секрета.\n */\nexport class SessionStorageTokenStorage implements TokenStorage {\n readonly #inner: TokenStorage;\n\n /** @param key ключ в `sessionStorage`. По умолчанию `itd-api:session`. */\n constructor(key = 'itd-api:session') {\n this.#inner = createTokenStorage(new SessionStorageKeyValueStore<ItdSession>(), { key });\n }\n\n get(): ItdSession | null {\n return this.#inner.get() as ItdSession | null;\n }\n\n set(session: ItdSession): void {\n void this.#inner.set(session);\n }\n\n clear(): void {\n void this.#inner.clear();\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "itd-api",
3
- "version": "0.7.2",
4
- "description": "Клиент REST и realtime API социальной сети итд.com для JavaScript и TypeScript",
3
+ "version": "0.9.0",
4
+ "description": "JS/TS SDK & API клиент для соцсети ИТД (итд.com)",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/KiowDev/itd-api.git"
@@ -18,7 +18,7 @@
18
18
  "rest-api",
19
19
  "client",
20
20
  "sdk",
21
- "realtime",
21
+ "events",
22
22
  "social",
23
23
  "typescript"
24
24
  ],
@@ -48,8 +48,8 @@
48
48
  "rest": [
49
49
  "./dist/rest/index.d.ts"
50
50
  ],
51
- "realtime": [
52
- "./dist/realtime/index.d.ts"
51
+ "events": [
52
+ "./dist/events/index.d.ts"
53
53
  ],
54
54
  "node": [
55
55
  "./dist/node/index.d.ts"
@@ -80,14 +80,14 @@
80
80
  "default": "./dist/rest/index.cjs"
81
81
  }
82
82
  },
83
- "./realtime": {
83
+ "./events": {
84
84
  "import": {
85
- "types": "./dist/realtime/index.d.ts",
86
- "default": "./dist/realtime/index.js"
85
+ "types": "./dist/events/index.d.ts",
86
+ "default": "./dist/events/index.js"
87
87
  },
88
88
  "require": {
89
- "types": "./dist/realtime/index.d.cts",
90
- "default": "./dist/realtime/index.cjs"
89
+ "types": "./dist/events/index.d.cts",
90
+ "default": "./dist/events/index.cjs"
91
91
  }
92
92
  },
93
93
  "./node": {
@@ -125,6 +125,7 @@
125
125
  "lint": "biome check src test packages",
126
126
  "lint:fix": "biome check --write src test packages",
127
127
  "check:layers": "node scripts/check-imports.mjs",
128
+ "check:public-feature": "tsc --project test/fixtures/tsconfig.public-feature.json && node scripts/check-public-feature.mjs",
128
129
  "measure:size": "node scripts/measure-bundles.mjs",
129
130
  "docs": "npm run docs:build",
130
131
  "docs:api": "node scripts/build-docs.mjs",
@@ -134,15 +135,15 @@
134
135
  "docs:check": "npm run docs:build",
135
136
  "check:pack": "publint && attw --pack .",
136
137
  "version": "npm run sync-version && git add src/core/version.ts",
137
- "prepublishOnly": "npm run typecheck && npm run check:layers && npm run test && npm run build && npm run check:pack"
138
+ "prepublishOnly": "npm run typecheck && npm run check:layers && npm run test && npm run build && npm run check:public-feature && npm run check:pack"
138
139
  },
139
140
  "devDependencies": {
140
141
  "@arethetypeswrong/cli": "^0.18.5",
141
- "@biomejs/biome": "^2.5.6",
142
- "@types/node": "^26.1.2",
142
+ "@biomejs/biome": "^2.5.7",
143
+ "@types/node": "^26.2.0",
143
144
  "@vitest/coverage-v8": "^4.1.10",
144
- "eventsource-parser": "^3.1.0",
145
- "publint": "^0.3.22",
145
+ "eventsource-parser": "^3.1.1",
146
+ "publint": "^0.3.23",
146
147
  "set-cookie-parser": "^3.1.2",
147
148
  "tsdown": "^0.22.14",
148
149
  "typedoc": "^0.28.20",
@@ -1,165 +0,0 @@
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_websocket = require("../shared/websocket-C_eI4H2o.cjs");
5
- const require_auth_provider = require("../shared/auth-provider-CG8oCQ9F.cjs");
6
- //#region src/realtime/client.ts
7
- /**
8
- * Поток уведомлений с собственным конвейером запросов.
9
- *
10
- * Тот же {@link ItdRealtime}, что отдаёт `itd.realtime()`, но собранный без полного клиента:
11
- * ресурсы, билдеры и сессия сюда не входят. Нужен приложениям, которым от API нужны только
12
- * события, — виджетам, счётчикам непрочитанного, фоновым слушателям.
13
- *
14
- * @example
15
- * ```ts
16
- * import { createRealtimeClient } from 'itd-api/realtime';
17
- *
18
- * await using stream = createRealtimeClient({ auth: token });
19
- * stream.on('notification', ({ notification }) => console.log(notification.type));
20
- * await stream.connect();
21
- * ```
22
- */
23
- var ItdRealtimeClient = class ItdRealtimeClient extends require_websocket.ItdRealtime {
24
- #runtime;
25
- /** Общий результат терминальной очистки для идемпотентных повторных вызовов. */
26
- #disposePromise;
27
- #disposed = false;
28
- constructor(options = {}) {
29
- const runtime = require_url.createClientRuntime(options, {
30
- catalog: require_url.ITD_CATALOG,
31
- auth: () => resolveAuthProvider(options.auth)
32
- });
33
- super(realtimeDeps(runtime), options);
34
- this.#runtime = runtime;
35
- require_websocket.setRealtimeConnectGuard(this, () => {
36
- if (!this.#disposed) return;
37
- throw new require_errors.ItdStateError("Поток уже окончательно освобождён через dispose(); нельзя подключить его снова. Создайте новый");
38
- });
39
- }
40
- /**
41
- * Окончательно освобождает поток и его конвейер: отключает соединение, дожидается
42
- * обработчиков и останавливает очередь запросов.
43
- *
44
- * Повторные вызовы возвращают тот же результат очистки.
45
- */
46
- dispose() {
47
- if (this.#disposePromise) return this.#disposePromise;
48
- this.#disposed = true;
49
- this.#disposePromise = this.#dispose();
50
- return this.#disposePromise;
51
- }
52
- async #dispose() {
53
- const errors = [];
54
- this.disconnect();
55
- try {
56
- await this.drain();
57
- } catch (error) {
58
- errors.push(error);
59
- }
60
- try {
61
- this.#runtime.close();
62
- await this.#runtime.dispose();
63
- } catch (error) {
64
- errors.push(error);
65
- }
66
- if (errors.length > 0) throw new AggregateError(errors, "Не удалось освободить поток");
67
- }
68
- /** Позволяет использовать поток с `await using`. */
69
- [Symbol.asyncDispose]() {
70
- return this.dispose();
71
- }
72
- static {
73
- require_url.installAsyncDisposeFallback(ItdRealtimeClient);
74
- }
75
- };
76
- /** Приводит опцию `auth` к провайдеру конвейера. */
77
- function resolveAuthProvider(auth) {
78
- if (auth === void 0) return require_auth_provider.anonymousAuth();
79
- return typeof auth === "string" ? require_auth_provider.bearerToken(auth) : auth;
80
- }
81
- /**
82
- * Связывает поток с собранным конвейером.
83
- *
84
- * Начальный счётчик непрочитанных берётся той же операцией, что и при опросе
85
- * (`realtime.poll.unread`): ресурс уведомлений потоку для этого не нужен.
86
- */
87
- function realtimeDeps(runtime) {
88
- const request = ({ operationId, path, query, signal }) => runtime.http.operation(operationId, {
89
- path,
90
- query,
91
- signal
92
- });
93
- return {
94
- baseUrl: runtime.config.baseUrl,
95
- fetch: runtime.config.fetch,
96
- clock: runtime.config.clock,
97
- logger: runtime.config.logger,
98
- request,
99
- baseHeaders: (url) => runtime.platformHeaders(url),
100
- getToken: () => runtime.auth.token(),
101
- refresh: () => runtime.auth.recover(),
102
- fetchUnreadCount: async () => {
103
- const payload = await request({
104
- operationId: "realtime.poll.unread",
105
- path: "/api/notifications/count"
106
- });
107
- return require_url.pickNumber(payload, "count", 0);
108
- }
109
- };
110
- }
111
- /**
112
- * Создаёт поток уведомлений с собственным конвейером. Равнозначно конструктору
113
- * {@link ItdRealtimeClient}.
114
- */
115
- function createRealtimeClient(options = {}) {
116
- return new ItdRealtimeClient(options);
117
- }
118
- //#endregion
119
- exports.DEFAULT_BASE_URL = require_url.DEFAULT_BASE_URL;
120
- exports.ItdAbortError = require_errors.ItdAbortError;
121
- exports.ItdApiError = require_errors.ItdApiError;
122
- exports.ItdApiErrorKind = require_errors.ItdApiErrorKind;
123
- exports.ItdAuthError = require_errors.ItdAuthError;
124
- exports.ItdConfigError = require_errors.ItdConfigError;
125
- exports.ItdError = require_errors.ItdError;
126
- exports.ItdErrorKind = require_errors.ItdErrorKind;
127
- exports.ItdForbiddenError = require_errors.ItdForbiddenError;
128
- exports.ItdNetworkError = require_errors.ItdNetworkError;
129
- exports.ItdNotFoundError = require_errors.ItdNotFoundError;
130
- exports.ItdRateLimitError = require_errors.ItdRateLimitError;
131
- exports.ItdRealtime = require_websocket.ItdRealtime;
132
- exports.ItdRealtimeClient = ItdRealtimeClient;
133
- exports.ItdServerError = require_errors.ItdServerError;
134
- exports.ItdStateError = require_errors.ItdStateError;
135
- exports.ItdTimeoutError = require_errors.ItdTimeoutError;
136
- exports.ItdValidationError = require_errors.ItdValidationError;
137
- exports.LIBRARY_VERSION = require_url.LIBRARY_VERSION;
138
- exports.NotificationType = require_url.NotificationType;
139
- exports.RealtimeComposer = require_websocket.RealtimeComposer;
140
- exports.RealtimeRouter = require_websocket.RealtimeRouter;
141
- exports.RealtimeStatus = require_url.RealtimeStatus;
142
- exports.RealtimeTransportKind = require_websocket.RealtimeTransportKind;
143
- exports.RealtimeUpdateOrigin = require_websocket.RealtimeUpdateOrigin;
144
- exports.RealtimeUpdateType = require_websocket.RealtimeUpdateType;
145
- exports.RuntimeMode = require_url.RuntimeMode;
146
- exports.UnauthorizedStreamError = require_websocket.UnauthorizedStreamError;
147
- exports.WebSocketTransport = require_websocket.WebSocketTransport;
148
- exports.anonymousAuth = require_auth_provider.anonymousAuth;
149
- exports.bearerToken = require_auth_provider.bearerToken;
150
- exports.canonicalNotificationType = require_url.canonicalNotificationType;
151
- exports.createRealtimeClient = createRealtimeClient;
152
- exports.formatNotificationText = require_url.formatNotificationText;
153
- exports.isItdApiError = require_errors.isItdApiError;
154
- exports.isItdAuthError = require_errors.isItdAuthError;
155
- exports.isItdError = require_errors.isItdError;
156
- exports.isItdRateLimitError = require_errors.isItdRateLimitError;
157
- exports.isItdStateError = require_errors.isItdStateError;
158
- exports.isKnownNotificationType = require_url.isKnownNotificationType;
159
- exports.normalizeNotification = require_url.normalizeNotification;
160
- exports.resolveNotificationUrl = require_url.resolveNotificationUrl;
161
- exports.runRealtimeMiddleware = require_websocket.runRealtimeMiddleware;
162
- exports.systemClock = require_url.systemClock;
163
- exports.tokenProvider = require_auth_provider.tokenProvider;
164
-
165
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","names":["ItdRealtime","#runtime","createClientRuntime","ITD_CATALOG","#disposed","ItdStateError","#disposePromise","#dispose","anonymousAuth","bearerToken","pickNumber"],"sources":["../../src/realtime/client.ts"],"sourcesContent":["import { installAsyncDisposeFallback } from '../core/async-dispose.js';\nimport { type AuthProvider, anonymousAuth, bearerToken } from '../core/auth-provider.js';\nimport { ItdStateError } from '../core/errors.js';\nimport { type ClientRuntime, createClientRuntime } from '../core/execution/client-runtime.js';\nimport type { RuntimeOptions } from '../core/options.js';\nimport { pickNumber } from '../core/unwrap.js';\nimport { ITD_CATALOG } from '../domain/catalog.js';\nimport {\n ItdRealtime,\n type RealtimeDeps,\n type RealtimeOptions,\n setRealtimeConnectGuard,\n} from './stream.js';\nimport type { RealtimeContext } from './updates.js';\n\n/** Опции конструктора {@link ItdRealtimeClient}. */\nexport interface RealtimeClientOptions<C extends RealtimeContext = RealtimeContext>\n extends RuntimeOptions,\n RealtimeOptions<C> {\n /**\n * Авторизация. Строка — сокращение для {@link bearerToken}.\n *\n * Без неё поток идёт анонимно. Токен считается готовым: продлевать его клиент не умеет,\n * а на отказ авторизации переподключение спрашивает токен заново. Сессия, которая входит\n * по паролю и продлевает себя сама, живёт в полном `ItdClient`.\n */\n auth?: string | AuthProvider | undefined;\n}\n\n/**\n * Поток уведомлений с собственным конвейером запросов.\n *\n * Тот же {@link ItdRealtime}, что отдаёт `itd.realtime()`, но собранный без полного клиента:\n * ресурсы, билдеры и сессия сюда не входят. Нужен приложениям, которым от API нужны только\n * события, — виджетам, счётчикам непрочитанного, фоновым слушателям.\n *\n * @example\n * ```ts\n * import { createRealtimeClient } from 'itd-api/realtime';\n *\n * await using stream = createRealtimeClient({ auth: token });\n * stream.on('notification', ({ notification }) => console.log(notification.type));\n * await stream.connect();\n * ```\n */\nexport class ItdRealtimeClient<C extends RealtimeContext = RealtimeContext> extends ItdRealtime<C> {\n readonly #runtime: ClientRuntime;\n /** Общий результат терминальной очистки для идемпотентных повторных вызовов. */\n #disposePromise: Promise<void> | undefined;\n #disposed = false;\n\n constructor(options: RealtimeClientOptions<C> = {}) {\n const runtime = createClientRuntime(options, {\n catalog: ITD_CATALOG,\n auth: () => resolveAuthProvider(options.auth),\n });\n\n super(realtimeDeps(runtime), options);\n this.#runtime = runtime;\n\n setRealtimeConnectGuard<C>(this, () => {\n if (!this.#disposed) return;\n throw new ItdStateError(\n 'Поток уже окончательно освобождён через dispose(); нельзя подключить его снова. ' +\n 'Создайте новый',\n );\n });\n }\n\n /**\n * Окончательно освобождает поток и его конвейер: отключает соединение, дожидается\n * обработчиков и останавливает очередь запросов.\n *\n * Повторные вызовы возвращают тот же результат очистки.\n */\n dispose(): Promise<void> {\n if (this.#disposePromise) return this.#disposePromise;\n this.#disposed = true;\n this.#disposePromise = this.#dispose();\n return this.#disposePromise;\n }\n\n async #dispose(): Promise<void> {\n const errors: unknown[] = [];\n this.disconnect();\n try {\n await this.drain();\n } catch (error) {\n errors.push(error);\n }\n try {\n this.#runtime.close();\n await this.#runtime.dispose();\n } catch (error) {\n errors.push(error);\n }\n if (errors.length > 0) throw new AggregateError(errors, 'Не удалось освободить поток');\n }\n\n /** Позволяет использовать поток с `await using`. */\n [Symbol.asyncDispose](): Promise<void> {\n return this.dispose();\n }\n\n static {\n installAsyncDisposeFallback(ItdRealtimeClient);\n }\n}\n\n/** Приводит опцию `auth` к провайдеру конвейера. */\nfunction resolveAuthProvider(auth: RealtimeClientOptions['auth']): AuthProvider {\n if (auth === undefined) return anonymousAuth();\n return typeof auth === 'string' ? bearerToken(auth) : auth;\n}\n\n/**\n * Связывает поток с собранным конвейером.\n *\n * Начальный счётчик непрочитанных берётся той же операцией, что и при опросе\n * (`realtime.poll.unread`): ресурс уведомлений потоку для этого не нужен.\n */\nfunction realtimeDeps(runtime: ClientRuntime): RealtimeDeps {\n const request: NonNullable<RealtimeDeps['request']> = ({ operationId, path, query, signal }) =>\n runtime.http.operation(operationId, { path, query, signal });\n\n return {\n baseUrl: runtime.config.baseUrl,\n fetch: runtime.config.fetch,\n clock: runtime.config.clock,\n logger: runtime.config.logger,\n request,\n baseHeaders: (url) => runtime.platformHeaders(url),\n getToken: () => runtime.auth.token(),\n refresh: () => runtime.auth.recover(),\n fetchUnreadCount: async () => {\n const payload = await request({\n operationId: 'realtime.poll.unread',\n path: '/api/notifications/count',\n });\n return pickNumber(payload, 'count', 0);\n },\n };\n}\n\n/**\n * Создаёт поток уведомлений с собственным конвейером. Равнозначно конструктору\n * {@link ItdRealtimeClient}.\n */\nexport function createRealtimeClient<C extends RealtimeContext = RealtimeContext>(\n options: RealtimeClientOptions<C> = {},\n): ItdRealtimeClient<C> {\n return new ItdRealtimeClient<C>(options);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6CA,IAAa,oBAAb,MAAa,0BAAuEA,kBAAAA,YAAe;CACjG;;CAEA;CACA,YAAY;CAEZ,YAAY,UAAoC,CAAC,GAAG;EAClD,MAAM,UAAUE,YAAAA,oBAAoB,SAAS;GAC3C,SAASC,YAAAA;GACT,YAAY,oBAAoB,QAAQ,IAAI;EAC9C,CAAC;EAED,MAAM,aAAa,OAAO,GAAG,OAAO;EACpC,KAAKF,WAAW;EAEhB,kBAAA,wBAA2B,YAAY;GACrC,IAAI,CAAC,KAAKG,WAAW;GACrB,MAAM,IAAIC,eAAAA,cACR,gGAEF;EACF,CAAC;CACH;;;;;;;CAQA,UAAyB;EACvB,IAAI,KAAKC,iBAAiB,OAAO,KAAKA;EACtC,KAAKF,YAAY;EACjB,KAAKE,kBAAkB,KAAKC,SAAS;EACrC,OAAO,KAAKD;CACd;CAEA,MAAMC,WAA0B;EAC9B,MAAM,SAAoB,CAAC;EAC3B,KAAK,WAAW;EAChB,IAAI;GACF,MAAM,KAAK,MAAM;EACnB,SAAS,OAAO;GACd,OAAO,KAAK,KAAK;EACnB;EACA,IAAI;GACF,KAAKN,SAAS,MAAM;GACpB,MAAM,KAAKA,SAAS,QAAQ;EAC9B,SAAS,OAAO;GACd,OAAO,KAAK,KAAK;EACnB;EACA,IAAI,OAAO,SAAS,GAAG,MAAM,IAAI,eAAe,QAAQ,6BAA6B;CACvF;;CAGA,CAAC,OAAO,gBAA+B;EACrC,OAAO,KAAK,QAAQ;CACtB;CAEA;EACE,YAAA,4BAA4B,iBAAiB;CAC/C;AACF;;AAGA,SAAS,oBAAoB,MAAmD;CAC9E,IAAI,SAAS,KAAA,GAAW,OAAOO,sBAAAA,cAAc;CAC7C,OAAO,OAAO,SAAS,WAAWC,sBAAAA,YAAY,IAAI,IAAI;AACxD;;;;;;;AAQA,SAAS,aAAa,SAAsC;CAC1D,MAAM,WAAiD,EAAE,aAAa,MAAM,OAAO,aACjF,QAAQ,KAAK,UAAU,aAAa;EAAE;EAAM;EAAO;CAAO,CAAC;CAE7D,OAAO;EACL,SAAS,QAAQ,OAAO;EACxB,OAAO,QAAQ,OAAO;EACtB,OAAO,QAAQ,OAAO;EACtB,QAAQ,QAAQ,OAAO;EACvB;EACA,cAAc,QAAQ,QAAQ,gBAAgB,GAAG;EACjD,gBAAgB,QAAQ,KAAK,MAAM;EACnC,eAAe,QAAQ,KAAK,QAAQ;EACpC,kBAAkB,YAAY;GAC5B,MAAM,UAAU,MAAM,QAAQ;IAC5B,aAAa;IACb,MAAM;GACR,CAAC;GACD,OAAOC,YAAAA,WAAW,SAAS,SAAS,CAAC;EACvC;CACF;AACF;;;;;AAMA,SAAgB,qBACd,UAAoC,CAAC,GACf;CACtB,OAAO,IAAI,kBAAqB,OAAO;AACzC"}
@@ -1,51 +0,0 @@
1
- import { B as Notification, C as ItdStateError, D as isItdAuthError, E as isItdApiError, Ft as Logger, I as isItdStateError, Mt as Unsubscribe, Nt as ClientHooks, P as isItdRateLimitError, R as NotificationEvent, S as ItdServerError, St as RealtimeStatus, T as ItdValidationError, V as NotificationSettings, Yt as RuntimeOptions, _ as ItdForbiddenError, a as ItdAbortError, at as DEFAULT_BASE_URL, bt as Loose, c as ItdApiErrorKind, en as RuntimeMode, et as AuthIdentity, f as ItdError, i as formatNotificationText, it as tokenProvider, jt as Listener, k as isItdError, l as ItdAuthError, n as canonicalNotificationType, nn as systemClock, nt as anonymousAuth, o as ItdApiError, p as ItdErrorKind, r as isKnownNotificationType, rt as bearerToken, st as LIBRARY_VERSION, t as resolveNotificationUrl, tn as ItdClock, tt as AuthProvider, u as ItdConfigError, v as ItdNetworkError, w as ItdTimeoutError, x as ItdRateLimitError, xt as NotificationType, y as ItdNotFoundError, z as normalizeNotification } from "../shared/url-DTfZ2toq.cjs";
2
- import { A as NotificationOfType, B as RealtimeUpdateOfType, C as RealtimeMiddlewareObj, D as RealtimeTypeGuard, E as RealtimeSequentializer, F as RealtimeNotificationSelector, G as RealtimeTransport, H as RealtimeUpdateType, I as RealtimeNotificationUpdate, J as UnauthorizedStreamError, K as TransportContext, L as RealtimeUnknownUpdate, M as RealtimeContextBase, N as RealtimeNotificationContext, O as runRealtimeMiddleware, P as RealtimeNotificationFilter, R as RealtimeUnreadCountUpdate, S as RealtimeMiddleware, T as RealtimePredicate, U as RealtimeRequest, V as RealtimeUpdateOrigin, W as RealtimeRequestInput, _ as RealtimeOptions, a as WebSocketTransportOptions, b as ReconnectOptions, c as RealtimeErrorContext, d as RealtimeMiddlewareLike, f as RealtimeRouteTable, g as RealtimeEvents, h as ItdRealtime, i as WebSocketTransport, j as RealtimeContext, k as NotificationEventOfType, l as RealtimeFilter, m as RealtimeRouter, n as WebSocketLike, o as RealtimeComposer, p as RealtimeRouteSelector, q as TransportEvent, r as WebSocketOpenFailureClassifier, s as RealtimeErrorBoundary, t as WebSocketImplementationOptions, u as RealtimeMiddlewareGroup, v as RealtimeTransportKind, w as RealtimeNext, x as RealtimeHandler, y as RealtimeEngineEvents, z as RealtimeUpdate } from "../shared/websocket-DF7XIMiX.cjs";
3
- //#region src/realtime/client.d.ts
4
- /** Опции конструктора {@link ItdRealtimeClient}. */
5
- interface RealtimeClientOptions<C extends RealtimeContext = RealtimeContext> extends RuntimeOptions, RealtimeOptions<C> {
6
- /**
7
- * Авторизация. Строка — сокращение для {@link bearerToken}.
8
- *
9
- * Без неё поток идёт анонимно. Токен считается готовым: продлевать его клиент не умеет,
10
- * а на отказ авторизации переподключение спрашивает токен заново. Сессия, которая входит
11
- * по паролю и продлевает себя сама, живёт в полном `ItdClient`.
12
- */
13
- auth?: string | AuthProvider | undefined;
14
- }
15
- /**
16
- * Поток уведомлений с собственным конвейером запросов.
17
- *
18
- * Тот же {@link ItdRealtime}, что отдаёт `itd.realtime()`, но собранный без полного клиента:
19
- * ресурсы, билдеры и сессия сюда не входят. Нужен приложениям, которым от API нужны только
20
- * события, — виджетам, счётчикам непрочитанного, фоновым слушателям.
21
- *
22
- * @example
23
- * ```ts
24
- * import { createRealtimeClient } from 'itd-api/realtime';
25
- *
26
- * await using stream = createRealtimeClient({ auth: token });
27
- * stream.on('notification', ({ notification }) => console.log(notification.type));
28
- * await stream.connect();
29
- * ```
30
- */
31
- declare class ItdRealtimeClient<C extends RealtimeContext = RealtimeContext> extends ItdRealtime<C> {
32
- #private;
33
- constructor(options?: RealtimeClientOptions<C>);
34
- /**
35
- * Окончательно освобождает поток и его конвейер: отключает соединение, дожидается
36
- * обработчиков и останавливает очередь запросов.
37
- *
38
- * Повторные вызовы возвращают тот же результат очистки.
39
- */
40
- dispose(): Promise<void>;
41
- /** Позволяет использовать поток с `await using`. */
42
- [Symbol.asyncDispose](): Promise<void>;
43
- }
44
- /**
45
- * Создаёт поток уведомлений с собственным конвейером. Равнозначно конструктору
46
- * {@link ItdRealtimeClient}.
47
- */
48
- declare function createRealtimeClient<C extends RealtimeContext = RealtimeContext>(options?: RealtimeClientOptions<C>): ItdRealtimeClient<C>;
49
- //#endregion
50
- export { type AuthIdentity, type AuthProvider, type ClientHooks, DEFAULT_BASE_URL, ItdAbortError, ItdApiError, ItdApiErrorKind, ItdAuthError, type ItdClock, ItdConfigError, ItdError, ItdErrorKind, ItdForbiddenError, ItdNetworkError, ItdNotFoundError, ItdRateLimitError, ItdRealtime, ItdRealtimeClient, ItdServerError, ItdStateError, ItdTimeoutError, ItdValidationError, LIBRARY_VERSION, type Listener, type Logger, type Loose, type Notification, type NotificationEvent, type NotificationEventOfType, type NotificationOfType, type NotificationSettings, NotificationType, type RealtimeClientOptions, RealtimeComposer, type RealtimeContext, type RealtimeContextBase, type RealtimeEngineEvents, type RealtimeErrorBoundary, type RealtimeErrorContext, type RealtimeEvents, type RealtimeFilter, type RealtimeHandler, type RealtimeMiddleware, type RealtimeMiddlewareGroup, type RealtimeMiddlewareLike, type RealtimeMiddlewareObj, type RealtimeNext, type RealtimeNotificationContext, type RealtimeNotificationFilter, type RealtimeNotificationSelector, type RealtimeNotificationUpdate, type RealtimeOptions, type RealtimePredicate, type RealtimeRequest, type RealtimeRequestInput, type RealtimeRouteSelector, type RealtimeRouteTable, RealtimeRouter, type RealtimeSequentializer, RealtimeStatus, type RealtimeTransport, RealtimeTransportKind, type RealtimeTypeGuard, type RealtimeUnknownUpdate, type RealtimeUnreadCountUpdate, type RealtimeUpdate, type RealtimeUpdateOfType, RealtimeUpdateOrigin, RealtimeUpdateType, type ReconnectOptions, RuntimeMode, type RuntimeOptions, type TransportContext, type TransportEvent, UnauthorizedStreamError, type Unsubscribe, type WebSocketImplementationOptions, type WebSocketLike, type WebSocketOpenFailureClassifier, WebSocketTransport, type WebSocketTransportOptions, anonymousAuth, bearerToken, canonicalNotificationType, createRealtimeClient, formatNotificationText, isItdApiError, isItdAuthError, isItdError, isItdRateLimitError, isItdStateError, isKnownNotificationType, normalizeNotification, resolveNotificationUrl, runRealtimeMiddleware, systemClock, tokenProvider };
51
- //# sourceMappingURL=index.d.cts.map
@@ -1,51 +0,0 @@
1
- import { B as Notification, C as ItdStateError, D as isItdAuthError, E as isItdApiError, Ft as Logger, I as isItdStateError, Mt as Unsubscribe, Nt as ClientHooks, P as isItdRateLimitError, R as NotificationEvent, S as ItdServerError, St as RealtimeStatus, T as ItdValidationError, V as NotificationSettings, Yt as RuntimeOptions, _ as ItdForbiddenError, a as ItdAbortError, at as DEFAULT_BASE_URL, bt as Loose, c as ItdApiErrorKind, en as RuntimeMode, et as AuthIdentity, f as ItdError, i as formatNotificationText, it as tokenProvider, jt as Listener, k as isItdError, l as ItdAuthError, n as canonicalNotificationType, nn as systemClock, nt as anonymousAuth, o as ItdApiError, p as ItdErrorKind, r as isKnownNotificationType, rt as bearerToken, st as LIBRARY_VERSION, t as resolveNotificationUrl, tn as ItdClock, tt as AuthProvider, u as ItdConfigError, v as ItdNetworkError, w as ItdTimeoutError, x as ItdRateLimitError, xt as NotificationType, y as ItdNotFoundError, z as normalizeNotification } from "../shared/url-DTfZ2toq.js";
2
- import { A as NotificationOfType, B as RealtimeUpdateOfType, C as RealtimeMiddlewareObj, D as RealtimeTypeGuard, E as RealtimeSequentializer, F as RealtimeNotificationSelector, G as RealtimeTransport, H as RealtimeUpdateType, I as RealtimeNotificationUpdate, J as UnauthorizedStreamError, K as TransportContext, L as RealtimeUnknownUpdate, M as RealtimeContextBase, N as RealtimeNotificationContext, O as runRealtimeMiddleware, P as RealtimeNotificationFilter, R as RealtimeUnreadCountUpdate, S as RealtimeMiddleware, T as RealtimePredicate, U as RealtimeRequest, V as RealtimeUpdateOrigin, W as RealtimeRequestInput, _ as RealtimeOptions, a as WebSocketTransportOptions, b as ReconnectOptions, c as RealtimeErrorContext, d as RealtimeMiddlewareLike, f as RealtimeRouteTable, g as RealtimeEvents, h as ItdRealtime, i as WebSocketTransport, j as RealtimeContext, k as NotificationEventOfType, l as RealtimeFilter, m as RealtimeRouter, n as WebSocketLike, o as RealtimeComposer, p as RealtimeRouteSelector, q as TransportEvent, r as WebSocketOpenFailureClassifier, s as RealtimeErrorBoundary, t as WebSocketImplementationOptions, u as RealtimeMiddlewareGroup, v as RealtimeTransportKind, w as RealtimeNext, x as RealtimeHandler, y as RealtimeEngineEvents, z as RealtimeUpdate } from "../shared/websocket-DYKBr8HF.js";
3
- //#region src/realtime/client.d.ts
4
- /** Опции конструктора {@link ItdRealtimeClient}. */
5
- interface RealtimeClientOptions<C extends RealtimeContext = RealtimeContext> extends RuntimeOptions, RealtimeOptions<C> {
6
- /**
7
- * Авторизация. Строка — сокращение для {@link bearerToken}.
8
- *
9
- * Без неё поток идёт анонимно. Токен считается готовым: продлевать его клиент не умеет,
10
- * а на отказ авторизации переподключение спрашивает токен заново. Сессия, которая входит
11
- * по паролю и продлевает себя сама, живёт в полном `ItdClient`.
12
- */
13
- auth?: string | AuthProvider | undefined;
14
- }
15
- /**
16
- * Поток уведомлений с собственным конвейером запросов.
17
- *
18
- * Тот же {@link ItdRealtime}, что отдаёт `itd.realtime()`, но собранный без полного клиента:
19
- * ресурсы, билдеры и сессия сюда не входят. Нужен приложениям, которым от API нужны только
20
- * события, — виджетам, счётчикам непрочитанного, фоновым слушателям.
21
- *
22
- * @example
23
- * ```ts
24
- * import { createRealtimeClient } from 'itd-api/realtime';
25
- *
26
- * await using stream = createRealtimeClient({ auth: token });
27
- * stream.on('notification', ({ notification }) => console.log(notification.type));
28
- * await stream.connect();
29
- * ```
30
- */
31
- declare class ItdRealtimeClient<C extends RealtimeContext = RealtimeContext> extends ItdRealtime<C> {
32
- #private;
33
- constructor(options?: RealtimeClientOptions<C>);
34
- /**
35
- * Окончательно освобождает поток и его конвейер: отключает соединение, дожидается
36
- * обработчиков и останавливает очередь запросов.
37
- *
38
- * Повторные вызовы возвращают тот же результат очистки.
39
- */
40
- dispose(): Promise<void>;
41
- /** Позволяет использовать поток с `await using`. */
42
- [Symbol.asyncDispose](): Promise<void>;
43
- }
44
- /**
45
- * Создаёт поток уведомлений с собственным конвейером. Равнозначно конструктору
46
- * {@link ItdRealtimeClient}.
47
- */
48
- declare function createRealtimeClient<C extends RealtimeContext = RealtimeContext>(options?: RealtimeClientOptions<C>): ItdRealtimeClient<C>;
49
- //#endregion
50
- export { type AuthIdentity, type AuthProvider, type ClientHooks, DEFAULT_BASE_URL, ItdAbortError, ItdApiError, ItdApiErrorKind, ItdAuthError, type ItdClock, ItdConfigError, ItdError, ItdErrorKind, ItdForbiddenError, ItdNetworkError, ItdNotFoundError, ItdRateLimitError, ItdRealtime, ItdRealtimeClient, ItdServerError, ItdStateError, ItdTimeoutError, ItdValidationError, LIBRARY_VERSION, type Listener, type Logger, type Loose, type Notification, type NotificationEvent, type NotificationEventOfType, type NotificationOfType, type NotificationSettings, NotificationType, type RealtimeClientOptions, RealtimeComposer, type RealtimeContext, type RealtimeContextBase, type RealtimeEngineEvents, type RealtimeErrorBoundary, type RealtimeErrorContext, type RealtimeEvents, type RealtimeFilter, type RealtimeHandler, type RealtimeMiddleware, type RealtimeMiddlewareGroup, type RealtimeMiddlewareLike, type RealtimeMiddlewareObj, type RealtimeNext, type RealtimeNotificationContext, type RealtimeNotificationFilter, type RealtimeNotificationSelector, type RealtimeNotificationUpdate, type RealtimeOptions, type RealtimePredicate, type RealtimeRequest, type RealtimeRequestInput, type RealtimeRouteSelector, type RealtimeRouteTable, RealtimeRouter, type RealtimeSequentializer, RealtimeStatus, type RealtimeTransport, RealtimeTransportKind, type RealtimeTypeGuard, type RealtimeUnknownUpdate, type RealtimeUnreadCountUpdate, type RealtimeUpdate, type RealtimeUpdateOfType, RealtimeUpdateOrigin, RealtimeUpdateType, type ReconnectOptions, RuntimeMode, type RuntimeOptions, type TransportContext, type TransportEvent, UnauthorizedStreamError, type Unsubscribe, type WebSocketImplementationOptions, type WebSocketLike, type WebSocketOpenFailureClassifier, WebSocketTransport, type WebSocketTransportOptions, anonymousAuth, bearerToken, canonicalNotificationType, createRealtimeClient, formatNotificationText, isItdApiError, isItdAuthError, isItdError, isItdRateLimitError, isItdStateError, isKnownNotificationType, normalizeNotification, resolveNotificationUrl, runRealtimeMiddleware, systemClock, tokenProvider };
51
- //# sourceMappingURL=index.d.ts.map