@mtcute/core 0.30.0 → 0.30.2

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 (148) hide show
  1. package/client.cjs +8 -0
  2. package/client.js +8 -0
  3. package/highlevel/client.d.cts +63 -1
  4. package/highlevel/client.d.ts +63 -1
  5. package/highlevel/methods/files/download-iterable.cjs +80 -45
  6. package/highlevel/methods/files/download-iterable.js +80 -45
  7. package/highlevel/methods/files/normalize-input-media.cjs +9 -1
  8. package/highlevel/methods/files/normalize-input-media.js +10 -2
  9. package/highlevel/methods/files/upload-file.cjs +6 -1
  10. package/highlevel/methods/files/upload-file.js +6 -1
  11. package/highlevel/methods/messages/create-rich-streaming-draft.cjs +39 -0
  12. package/highlevel/methods/messages/create-rich-streaming-draft.d.cts +42 -0
  13. package/highlevel/methods/messages/create-rich-streaming-draft.d.ts +42 -0
  14. package/highlevel/methods/messages/create-rich-streaming-draft.js +34 -0
  15. package/highlevel/methods/messages/normalize-rich-message.cjs +168 -0
  16. package/highlevel/methods/messages/normalize-rich-message.d.cts +10 -0
  17. package/highlevel/methods/messages/normalize-rich-message.d.ts +10 -0
  18. package/highlevel/methods/messages/normalize-rich-message.js +163 -0
  19. package/highlevel/methods/messages/send-common.cjs +3 -2
  20. package/highlevel/methods/messages/send-common.d.cts +4 -1
  21. package/highlevel/methods/messages/send-common.d.ts +4 -1
  22. package/highlevel/methods/messages/send-common.js +3 -2
  23. package/highlevel/methods/messages/send-rich-message.cjs +49 -0
  24. package/highlevel/methods/messages/send-rich-message.d.cts +38 -0
  25. package/highlevel/methods/messages/send-rich-message.d.ts +38 -0
  26. package/highlevel/methods/messages/send-rich-message.js +44 -0
  27. package/highlevel/methods.d.cts +3 -0
  28. package/highlevel/methods.d.ts +3 -0
  29. package/highlevel/types/bots/inline-message/factories.cjs +14 -0
  30. package/highlevel/types/bots/inline-message/factories.d.cts +9 -1
  31. package/highlevel/types/bots/inline-message/factories.d.ts +9 -1
  32. package/highlevel/types/bots/inline-message/factories.js +14 -0
  33. package/highlevel/types/bots/inline-message/types.d.cts +17 -1
  34. package/highlevel/types/bots/inline-message/types.d.ts +17 -1
  35. package/highlevel/types/files/utils.d.cts +9 -0
  36. package/highlevel/types/files/utils.d.ts +9 -0
  37. package/highlevel/types/media/input-media/types.d.cts +1 -1
  38. package/highlevel/types/media/input-media/types.d.ts +1 -1
  39. package/highlevel/types/messages/index.d.cts +1 -1
  40. package/highlevel/types/messages/index.d.ts +1 -1
  41. package/highlevel/types/messages/message.cjs +1 -1
  42. package/highlevel/types/messages/message.d.cts +1 -1
  43. package/highlevel/types/messages/message.d.ts +1 -1
  44. package/highlevel/types/messages/message.js +1 -1
  45. package/highlevel/types/messages/rich/index.d.cts +4 -0
  46. package/highlevel/types/messages/rich/index.d.ts +4 -0
  47. package/highlevel/types/messages/rich/inner.cjs +219 -0
  48. package/highlevel/types/messages/rich/inner.d.cts +127 -0
  49. package/highlevel/types/messages/rich/inner.d.ts +127 -0
  50. package/highlevel/types/messages/rich/inner.js +214 -0
  51. package/highlevel/types/messages/{rich-message.cjs → rich/rich-message.cjs} +6 -6
  52. package/highlevel/types/messages/{rich-message.d.cts → rich/rich-message.d.cts} +5 -5
  53. package/highlevel/types/messages/{rich-message.d.ts → rich/rich-message.d.ts} +5 -5
  54. package/highlevel/types/messages/{rich-message.js → rich/rich-message.js} +6 -6
  55. package/highlevel/types/messages/rich/types.d.cts +76 -0
  56. package/highlevel/types/messages/rich/types.d.ts +76 -0
  57. package/highlevel/updates/manager.cjs +10 -169
  58. package/highlevel/updates/manager.js +10 -169
  59. package/highlevel/utils/entities.cjs +176 -0
  60. package/highlevel/utils/entities.d.cts +18 -0
  61. package/highlevel/utils/entities.d.ts +18 -0
  62. package/highlevel/utils/entities.js +177 -1
  63. package/highlevel/utils/index.d.cts +1 -0
  64. package/highlevel/utils/index.d.ts +1 -0
  65. package/highlevel/utils/walk-page-blocks.cjs +164 -0
  66. package/highlevel/utils/walk-page-blocks.d.cts +9 -0
  67. package/highlevel/utils/walk-page-blocks.d.ts +9 -0
  68. package/highlevel/utils/walk-page-blocks.js +159 -0
  69. package/index.cjs +3 -1
  70. package/index.js +3 -1
  71. package/methods.cjs +4 -0
  72. package/methods.js +4 -0
  73. package/network/authorization.cjs +1 -1
  74. package/network/authorization.js +1 -1
  75. package/network/delay-gate.cjs +29 -0
  76. package/network/delay-gate.d.cts +5 -0
  77. package/network/delay-gate.d.ts +5 -0
  78. package/network/delay-gate.js +24 -0
  79. package/network/delay-gate.test.d.cts +1 -0
  80. package/network/delay-gate.test.d.ts +1 -0
  81. package/network/message-id-store.cjs +30 -0
  82. package/network/message-id-store.d.cts +7 -0
  83. package/network/message-id-store.d.ts +7 -0
  84. package/network/message-id-store.js +25 -0
  85. package/network/message-id-store.test.d.cts +1 -0
  86. package/network/message-id-store.test.d.ts +1 -0
  87. package/network/middlewares/bundle.cjs +2 -0
  88. package/network/middlewares/bundle.d.cts +1 -0
  89. package/network/middlewares/bundle.d.ts +1 -0
  90. package/network/middlewares/bundle.js +2 -0
  91. package/network/middlewares/default.cjs +6 -1
  92. package/network/middlewares/default.js +6 -1
  93. package/network/middlewares/flood-waiter.test.d.cts +1 -0
  94. package/network/middlewares/flood-waiter.test.d.ts +1 -0
  95. package/network/middlewares/internal-errors.test.d.cts +1 -0
  96. package/network/middlewares/internal-errors.test.d.ts +1 -0
  97. package/network/middlewares/media-throttle.cjs +65 -0
  98. package/network/middlewares/media-throttle.d.cts +5 -0
  99. package/network/middlewares/media-throttle.d.ts +5 -0
  100. package/network/middlewares/media-throttle.js +60 -0
  101. package/network/middlewares/media-throttle.test.d.cts +1 -0
  102. package/network/middlewares/media-throttle.test.d.ts +1 -0
  103. package/network/middlewares/on-error.test.d.cts +1 -0
  104. package/network/middlewares/on-error.test.d.ts +1 -0
  105. package/network/middlewares/on-method.test.d.cts +1 -0
  106. package/network/middlewares/on-method.test.d.ts +1 -0
  107. package/network/mtproto-session.cjs +9 -2
  108. package/network/mtproto-session.d.cts +5 -2
  109. package/network/mtproto-session.d.ts +5 -2
  110. package/network/mtproto-session.js +9 -2
  111. package/network/mtproxy/_fake-tls.cjs +169 -107
  112. package/network/mtproxy/_fake-tls.js +169 -107
  113. package/network/mtproxy/_fake-tls.test.d.cts +1 -0
  114. package/network/mtproxy/_fake-tls.test.d.ts +1 -0
  115. package/network/multi-session-connection.cjs +7 -0
  116. package/network/multi-session-connection.d.cts +2 -0
  117. package/network/multi-session-connection.d.ts +2 -0
  118. package/network/multi-session-connection.js +7 -0
  119. package/network/network-manager.cjs +7 -1
  120. package/network/network-manager.js +7 -1
  121. package/network/resource-limiter.cjs +60 -0
  122. package/network/resource-limiter.d.cts +11 -0
  123. package/network/resource-limiter.d.ts +11 -0
  124. package/network/resource-limiter.js +55 -0
  125. package/network/resource-limiter.test.d.cts +1 -0
  126. package/network/resource-limiter.test.d.ts +1 -0
  127. package/network/server-salt.cjs +7 -3
  128. package/network/server-salt.d.cts +2 -0
  129. package/network/server-salt.d.ts +2 -0
  130. package/network/server-salt.js +7 -3
  131. package/network/session-connection.cjs +106 -20
  132. package/network/session-connection.d.cts +11 -0
  133. package/network/session-connection.d.ts +11 -0
  134. package/network/session-connection.js +106 -20
  135. package/package.json +1 -1
  136. package/tl/api-schema.json +1 -1
  137. package/tl/binary/reader.cjs +115 -109
  138. package/tl/binary/reader.js +115 -109
  139. package/tl/binary/writer.cjs +243 -245
  140. package/tl/binary/writer.js +243 -245
  141. package/tl/index.d.cts +227 -216
  142. package/tl/index.d.ts +227 -216
  143. package/tl/inner-tl.cjs +3 -1
  144. package/tl/inner-tl.js +3 -1
  145. package/types/utils.d.cts +4 -0
  146. package/types/utils.d.ts +4 -0
  147. package/utils.cjs +4 -0
  148. package/utils.js +5 -1
package/client.cjs CHANGED
@@ -159,6 +159,7 @@ const iterInviteLinks = require("./highlevel/methods/invite-links/iter-invite-li
159
159
  const revokeInviteLink = require("./highlevel/methods/invite-links/revoke-invite-link.cjs");
160
160
  const appendTodoList = require("./highlevel/methods/messages/append-todo-list.cjs");
161
161
  const closePoll = require("./highlevel/methods/messages/close-poll.cjs");
162
+ const createRichStreamingDraft = require("./highlevel/methods/messages/create-rich-streaming-draft.cjs");
162
163
  const createStreamingDraft = require("./highlevel/methods/messages/create-streaming-draft.cjs");
163
164
  const deleteMessages = require("./highlevel/methods/messages/delete-messages.cjs");
164
165
  const deleteScheduledMessages = require("./highlevel/methods/messages/delete-scheduled-messages.cjs");
@@ -201,6 +202,7 @@ const sendPaidReaction = require("./highlevel/methods/messages/send-paid-reactio
201
202
  const sendQuote = require("./highlevel/methods/messages/send-quote.cjs");
202
203
  const sendReaction = require("./highlevel/methods/messages/send-reaction.cjs");
203
204
  const sendReply = require("./highlevel/methods/messages/send-reply.cjs");
205
+ const sendRichMessage = require("./highlevel/methods/messages/send-rich-message.cjs");
204
206
  const sendScheduled = require("./highlevel/methods/messages/send-scheduled.cjs");
205
207
  const sendText = require("./highlevel/methods/messages/send-text.cjs");
206
208
  const sendTyping = require("./highlevel/methods/messages/send-typing.cjs");
@@ -931,6 +933,9 @@ TelegramClient.prototype.appendTodoList = function(...args) {
931
933
  TelegramClient.prototype.closePoll = function(...args) {
932
934
  return closePoll.closePoll(this._client, ...args);
933
935
  };
936
+ TelegramClient.prototype.createRichStreamingDraft = function(...args) {
937
+ return createRichStreamingDraft.createRichStreamingDraft(this._client, ...args);
938
+ };
934
939
  TelegramClient.prototype.createStreamingDraft = function(...args) {
935
940
  return createStreamingDraft.createStreamingDraft(this._client, ...args);
936
941
  };
@@ -1093,6 +1098,9 @@ TelegramClient.prototype.replyMedia = function(...args) {
1093
1098
  TelegramClient.prototype.replyMediaGroup = function(...args) {
1094
1099
  return sendReply.replyMediaGroup(this._client, ...args);
1095
1100
  };
1101
+ TelegramClient.prototype.sendRichMessage = function(...args) {
1102
+ return sendRichMessage.sendRichMessage(this._client, ...args);
1103
+ };
1096
1104
  TelegramClient.prototype.sendScheduled = function(...args) {
1097
1105
  return sendScheduled.sendScheduled(this._client, ...args);
1098
1106
  };
package/client.js CHANGED
@@ -152,6 +152,7 @@ import { iterInviteLinks } from "./highlevel/methods/invite-links/iter-invite-li
152
152
  import { revokeInviteLink } from "./highlevel/methods/invite-links/revoke-invite-link.js";
153
153
  import { appendTodoList } from "./highlevel/methods/messages/append-todo-list.js";
154
154
  import { closePoll } from "./highlevel/methods/messages/close-poll.js";
155
+ import { createRichStreamingDraft } from "./highlevel/methods/messages/create-rich-streaming-draft.js";
155
156
  import { createStreamingDraft } from "./highlevel/methods/messages/create-streaming-draft.js";
156
157
  import { deleteMessagesById, deleteMessages } from "./highlevel/methods/messages/delete-messages.js";
157
158
  import { deleteScheduledMessages } from "./highlevel/methods/messages/delete-scheduled-messages.js";
@@ -194,6 +195,7 @@ import { sendPaidReaction } from "./highlevel/methods/messages/send-paid-reactio
194
195
  import { quoteWithText, quoteWithMedia, quoteWithMediaGroup } from "./highlevel/methods/messages/send-quote.js";
195
196
  import { sendReaction } from "./highlevel/methods/messages/send-reaction.js";
196
197
  import { replyText, replyMedia, replyMediaGroup } from "./highlevel/methods/messages/send-reply.js";
198
+ import { sendRichMessage } from "./highlevel/methods/messages/send-rich-message.js";
197
199
  import { sendScheduled } from "./highlevel/methods/messages/send-scheduled.js";
198
200
  import { sendText } from "./highlevel/methods/messages/send-text.js";
199
201
  import { sendTyping } from "./highlevel/methods/messages/send-typing.js";
@@ -924,6 +926,9 @@ TelegramClient.prototype.appendTodoList = function(...args) {
924
926
  TelegramClient.prototype.closePoll = function(...args) {
925
927
  return closePoll(this._client, ...args);
926
928
  };
929
+ TelegramClient.prototype.createRichStreamingDraft = function(...args) {
930
+ return createRichStreamingDraft(this._client, ...args);
931
+ };
927
932
  TelegramClient.prototype.createStreamingDraft = function(...args) {
928
933
  return createStreamingDraft(this._client, ...args);
929
934
  };
@@ -1086,6 +1091,9 @@ TelegramClient.prototype.replyMedia = function(...args) {
1086
1091
  TelegramClient.prototype.replyMediaGroup = function(...args) {
1087
1092
  return replyMediaGroup(this._client, ...args);
1088
1093
  };
1094
+ TelegramClient.prototype.sendRichMessage = function(...args) {
1095
+ return sendRichMessage(this._client, ...args);
1096
+ };
1089
1097
  TelegramClient.prototype.sendScheduled = function(...args) {
1090
1098
  return sendScheduled(this._client, ...args);
1091
1099
  };
@@ -12,6 +12,7 @@ import { GetForumTopicsOffset, getForumTopics } from './methods/forums/get-forum
12
12
  import { InputStarGiftAttributeIds, ResaleStarGiftsMeta } from './methods/gifts/get-resale-star-gifts.js';
13
13
  import { StarGiftUpgradeOptions } from './methods/gifts/get-star-gift-upgrade-options.js';
14
14
  import { GetInviteLinksOffset, getInviteLinks } from './methods/invite-links/get-invite-links.js';
15
+ import { RichStreamingDraft } from './methods/messages/create-rich-streaming-draft.js';
15
16
  import { StreamingDraft } from './methods/messages/create-streaming-draft.js';
16
17
  import { DeleteMessagesParams } from './methods/messages/delete-messages.js';
17
18
  import { ForwardMessageOptions } from './methods/messages/forward-messages.js';
@@ -29,7 +30,7 @@ import { InputStarsAmount } from './methods/premium/_normalize-stars-amount.js';
29
30
  import { CanApplyBoostResult } from './methods/premium/can-apply-boost.js';
30
31
  import { CanSendStoryResult } from './methods/stories/can-send-story.js';
31
32
  import { ITelegramStorageProvider } from './storage/provider.js';
32
- import { AllStories, ArrayPaginated, ArrayPaginatedWithMeta, ArrayWithTotal, Audio, Boost, BoostSlot, BoostStats, BotChatJoinRequestUpdate, BotCommands, BotGuestChatQuery, BotReactionCountUpdate, BotReactionUpdate, BotStoppedUpdate, BusinessCallbackQuery, BusinessChatLink, BusinessConnection, BusinessMessage, BusinessWorkHoursDay, CallbackQuery, Chat, ChatEvent, ChatInviteLink, ChatInviteLinkMember, ChatJoinRequestUpdate, ChatlistPreview, ChatMember, ChatMemberUpdate, ChatPreview, ChosenInlineResult, CollectibleInfo, DeleteBusinessMessageUpdate, DeleteMessageUpdate, DeleteStoryUpdate, Dialog, FactCheck, FileDownloadLocation, FileDownloadParameters, ForumTopic, FullChat, FullUser, GameHighScore, HistoryReadUpdate, InlineCallbackQuery, InlineQuery, InputChatEventFilters, InputDialogFolder, InputDocumentId, InputFileLike, InputInlineMessage, InputInlineResult, InputMediaAudio, InputMediaLike, InputMediaSticker, InputMessageId, InputPeerLike, InputPrivacyRule, InputReaction, InputStarGift, InputStickerSet, InputStickerSetItem, InputText, InputWebview, MaybeDynamic, Message, MessageEffect, MessageMedia, MessageReactions, ParametersSkip2, ParsedUpdate, Peer, PeerReaction, PeerSettings, PeerStories, Photo, Poll, PollUpdate, PollVoteUpdate, PreCheckoutQuery, RawDocument, ReplyMarkup, SavedStarGift, SentCode, StarGift, StarGiftUnique, StarGiftValue, StarsStatus, StarsTransaction, Sticker, StickerSet, StickerType, StoriesStealthMode, Story, StoryInteractions, StoryUpdate, StoryViewer, StoryViewersList, TakeoutSession, TextWithEntities, TypingStatus, UploadedFile, UploadFileLike, User, UserStatusUpdate, UserTypingUpdate, WebPageMedia, WebviewResult } from './types/index.js';
33
+ import { AllStories, ArrayPaginated, ArrayPaginatedWithMeta, ArrayWithTotal, Audio, Boost, BoostSlot, BoostStats, BotChatJoinRequestUpdate, BotCommands, BotGuestChatQuery, BotReactionCountUpdate, BotReactionUpdate, BotStoppedUpdate, BusinessCallbackQuery, BusinessChatLink, BusinessConnection, BusinessMessage, BusinessWorkHoursDay, CallbackQuery, Chat, ChatEvent, ChatInviteLink, ChatInviteLinkMember, ChatJoinRequestUpdate, ChatlistPreview, ChatMember, ChatMemberUpdate, ChatPreview, ChosenInlineResult, CollectibleInfo, DeleteBusinessMessageUpdate, DeleteMessageUpdate, DeleteStoryUpdate, Dialog, FactCheck, FileDownloadLocation, FileDownloadParameters, ForumTopic, FullChat, FullUser, GameHighScore, HistoryReadUpdate, InlineCallbackQuery, InlineQuery, InputChatEventFilters, InputDialogFolder, InputDocumentId, InputFileLike, InputInlineMessage, InputInlineResult, InputMediaAudio, InputMediaLike, InputMediaSticker, InputMessageId, InputPeerLike, InputPrivacyRule, InputReaction, InputRichMessage, InputStarGift, InputStickerSet, InputStickerSetItem, InputText, InputWebview, MaybeDynamic, Message, MessageEffect, MessageMedia, MessageReactions, ParametersSkip2, ParsedUpdate, Peer, PeerReaction, PeerSettings, PeerStories, Photo, Poll, PollUpdate, PollVoteUpdate, PreCheckoutQuery, RawDocument, ReplyMarkup, RichMediaUploadCache, SavedStarGift, SentCode, StarGift, StarGiftUnique, StarGiftValue, StarsStatus, StarsTransaction, Sticker, StickerSet, StickerType, StoriesStealthMode, Story, StoryInteractions, StoryUpdate, StoryViewer, StoryViewersList, TakeoutSession, TextWithEntities, TypingStatus, UploadedFile, UploadFileLike, User, UserStatusUpdate, UserTypingUpdate, WebPageMedia, WebviewResult } from './types/index.js';
33
34
  import { ParsedUpdateHandlerParams } from './updates/parsed.js';
34
35
  import { RawUpdateInfo } from './updates/types.js';
35
36
  import { InputStringSessionData } from './utils/string-session.js';
@@ -3092,6 +3093,34 @@ export interface TelegramClient extends ITelegramClient {
3092
3093
  */
3093
3094
  shouldDispatch?: true;
3094
3095
  }): Promise<Poll>;
3096
+ /**
3097
+ * Create a streaming rich message draft
3098
+ *
3099
+ * **Available**: 👤 users only
3100
+ *
3101
+ * @param chatId Chat ID
3102
+ * @param params
3103
+ */
3104
+ createRichStreamingDraft(chatId: InputPeerLike, params?: {
3105
+ /**
3106
+ * Unique identifier of the business connection on behalf of which the action will be sent
3107
+ */
3108
+ businessConnectionId?: string;
3109
+ /** Whether to disable upload cache (exists to prevent uploading the same media multiple times) */
3110
+ disableUploadCache?: boolean;
3111
+ /**
3112
+ * For comment threads, ID of the thread (i.e. top message)
3113
+ */
3114
+ threadId?: number;
3115
+ /**
3116
+ * Function that will be called after some part of the media has been uploaded.
3117
+ *
3118
+ * @param id ID of the file being uploaded
3119
+ * @param uploaded Number of bytes already uploaded
3120
+ * @param total Total file size
3121
+ */
3122
+ progressCallback?: (id: string, uploaded: number, total: number) => void;
3123
+ }): Promise<RichStreamingDraft>;
3095
3124
  /**
3096
3125
  * Create a streaming text message draft
3097
3126
  *
@@ -4093,6 +4122,39 @@ export interface TelegramClient extends ITelegramClient {
4093
4122
  replyMedia(message: Message, ...params: ParametersSkip2<typeof sendMedia>): ReturnType<typeof sendMedia>;
4094
4123
  /** Send a media group in reply to a given message */
4095
4124
  replyMediaGroup(message: Message, ...params: ParametersSkip2<typeof sendMediaGroup>): ReturnType<typeof sendMediaGroup>;
4125
+ /**
4126
+ * Send a rich message
4127
+ *
4128
+ * **Available**: 👤 users only
4129
+ *
4130
+ * @param chatId ID of the chat, its username, phone or `"me"` or `"self"`
4131
+ * @param params Rich message contents and additional sending parameters
4132
+ */
4133
+ sendRichMessage(chatId: InputPeerLike, params: CommonSendParams & {
4134
+ content: InputRichMessage;
4135
+ /** Override the default random ID, for streaming drafts */
4136
+ randomId?: Long;
4137
+ /**
4138
+ * For bots: inline or reply markup or an instruction
4139
+ * to hide a reply keyboard or to force a reply.
4140
+ */
4141
+ replyMarkup?: ReplyMarkup;
4142
+ /**
4143
+ * Function that will be called after some part has been uploaded.
4144
+ *
4145
+ * @param id ID of the file being uploaded
4146
+ * @param uploaded Number of bytes already uploaded
4147
+ * @param total Total file size
4148
+ */
4149
+ progressCallback?: (id: string, uploaded: number, total: number) => void;
4150
+ /**
4151
+ * Cache for uploaded media, used to avoid re-uploading the same media multiple times.
4152
+ *
4153
+ * Pass a (potentially shared) {@link RichMediaUploadCache} to reuse media uploaded
4154
+ * by an earlier call (e.g. a streaming draft) instead of uploading it again.
4155
+ */
4156
+ uploadCache?: RichMediaUploadCache;
4157
+ }): Promise<Message>;
4096
4158
  /**
4097
4159
  * Send previously scheduled message(s)
4098
4160
  *
@@ -12,6 +12,7 @@ import { GetForumTopicsOffset, getForumTopics } from './methods/forums/get-forum
12
12
  import { InputStarGiftAttributeIds, ResaleStarGiftsMeta } from './methods/gifts/get-resale-star-gifts.js';
13
13
  import { StarGiftUpgradeOptions } from './methods/gifts/get-star-gift-upgrade-options.js';
14
14
  import { GetInviteLinksOffset, getInviteLinks } from './methods/invite-links/get-invite-links.js';
15
+ import { RichStreamingDraft } from './methods/messages/create-rich-streaming-draft.js';
15
16
  import { StreamingDraft } from './methods/messages/create-streaming-draft.js';
16
17
  import { DeleteMessagesParams } from './methods/messages/delete-messages.js';
17
18
  import { ForwardMessageOptions } from './methods/messages/forward-messages.js';
@@ -29,7 +30,7 @@ import { InputStarsAmount } from './methods/premium/_normalize-stars-amount.js';
29
30
  import { CanApplyBoostResult } from './methods/premium/can-apply-boost.js';
30
31
  import { CanSendStoryResult } from './methods/stories/can-send-story.js';
31
32
  import { ITelegramStorageProvider } from './storage/provider.js';
32
- import { AllStories, ArrayPaginated, ArrayPaginatedWithMeta, ArrayWithTotal, Audio, Boost, BoostSlot, BoostStats, BotChatJoinRequestUpdate, BotCommands, BotGuestChatQuery, BotReactionCountUpdate, BotReactionUpdate, BotStoppedUpdate, BusinessCallbackQuery, BusinessChatLink, BusinessConnection, BusinessMessage, BusinessWorkHoursDay, CallbackQuery, Chat, ChatEvent, ChatInviteLink, ChatInviteLinkMember, ChatJoinRequestUpdate, ChatlistPreview, ChatMember, ChatMemberUpdate, ChatPreview, ChosenInlineResult, CollectibleInfo, DeleteBusinessMessageUpdate, DeleteMessageUpdate, DeleteStoryUpdate, Dialog, FactCheck, FileDownloadLocation, FileDownloadParameters, ForumTopic, FullChat, FullUser, GameHighScore, HistoryReadUpdate, InlineCallbackQuery, InlineQuery, InputChatEventFilters, InputDialogFolder, InputDocumentId, InputFileLike, InputInlineMessage, InputInlineResult, InputMediaAudio, InputMediaLike, InputMediaSticker, InputMessageId, InputPeerLike, InputPrivacyRule, InputReaction, InputStarGift, InputStickerSet, InputStickerSetItem, InputText, InputWebview, MaybeDynamic, Message, MessageEffect, MessageMedia, MessageReactions, ParametersSkip2, ParsedUpdate, Peer, PeerReaction, PeerSettings, PeerStories, Photo, Poll, PollUpdate, PollVoteUpdate, PreCheckoutQuery, RawDocument, ReplyMarkup, SavedStarGift, SentCode, StarGift, StarGiftUnique, StarGiftValue, StarsStatus, StarsTransaction, Sticker, StickerSet, StickerType, StoriesStealthMode, Story, StoryInteractions, StoryUpdate, StoryViewer, StoryViewersList, TakeoutSession, TextWithEntities, TypingStatus, UploadedFile, UploadFileLike, User, UserStatusUpdate, UserTypingUpdate, WebPageMedia, WebviewResult } from './types/index.js';
33
+ import { AllStories, ArrayPaginated, ArrayPaginatedWithMeta, ArrayWithTotal, Audio, Boost, BoostSlot, BoostStats, BotChatJoinRequestUpdate, BotCommands, BotGuestChatQuery, BotReactionCountUpdate, BotReactionUpdate, BotStoppedUpdate, BusinessCallbackQuery, BusinessChatLink, BusinessConnection, BusinessMessage, BusinessWorkHoursDay, CallbackQuery, Chat, ChatEvent, ChatInviteLink, ChatInviteLinkMember, ChatJoinRequestUpdate, ChatlistPreview, ChatMember, ChatMemberUpdate, ChatPreview, ChosenInlineResult, CollectibleInfo, DeleteBusinessMessageUpdate, DeleteMessageUpdate, DeleteStoryUpdate, Dialog, FactCheck, FileDownloadLocation, FileDownloadParameters, ForumTopic, FullChat, FullUser, GameHighScore, HistoryReadUpdate, InlineCallbackQuery, InlineQuery, InputChatEventFilters, InputDialogFolder, InputDocumentId, InputFileLike, InputInlineMessage, InputInlineResult, InputMediaAudio, InputMediaLike, InputMediaSticker, InputMessageId, InputPeerLike, InputPrivacyRule, InputReaction, InputRichMessage, InputStarGift, InputStickerSet, InputStickerSetItem, InputText, InputWebview, MaybeDynamic, Message, MessageEffect, MessageMedia, MessageReactions, ParametersSkip2, ParsedUpdate, Peer, PeerReaction, PeerSettings, PeerStories, Photo, Poll, PollUpdate, PollVoteUpdate, PreCheckoutQuery, RawDocument, ReplyMarkup, RichMediaUploadCache, SavedStarGift, SentCode, StarGift, StarGiftUnique, StarGiftValue, StarsStatus, StarsTransaction, Sticker, StickerSet, StickerType, StoriesStealthMode, Story, StoryInteractions, StoryUpdate, StoryViewer, StoryViewersList, TakeoutSession, TextWithEntities, TypingStatus, UploadedFile, UploadFileLike, User, UserStatusUpdate, UserTypingUpdate, WebPageMedia, WebviewResult } from './types/index.js';
33
34
  import { ParsedUpdateHandlerParams } from './updates/parsed.js';
34
35
  import { RawUpdateInfo } from './updates/types.js';
35
36
  import { InputStringSessionData } from './utils/string-session.js';
@@ -3092,6 +3093,34 @@ export interface TelegramClient extends ITelegramClient {
3092
3093
  */
3093
3094
  shouldDispatch?: true;
3094
3095
  }): Promise<Poll>;
3096
+ /**
3097
+ * Create a streaming rich message draft
3098
+ *
3099
+ * **Available**: 👤 users only
3100
+ *
3101
+ * @param chatId Chat ID
3102
+ * @param params
3103
+ */
3104
+ createRichStreamingDraft(chatId: InputPeerLike, params?: {
3105
+ /**
3106
+ * Unique identifier of the business connection on behalf of which the action will be sent
3107
+ */
3108
+ businessConnectionId?: string;
3109
+ /** Whether to disable upload cache (exists to prevent uploading the same media multiple times) */
3110
+ disableUploadCache?: boolean;
3111
+ /**
3112
+ * For comment threads, ID of the thread (i.e. top message)
3113
+ */
3114
+ threadId?: number;
3115
+ /**
3116
+ * Function that will be called after some part of the media has been uploaded.
3117
+ *
3118
+ * @param id ID of the file being uploaded
3119
+ * @param uploaded Number of bytes already uploaded
3120
+ * @param total Total file size
3121
+ */
3122
+ progressCallback?: (id: string, uploaded: number, total: number) => void;
3123
+ }): Promise<RichStreamingDraft>;
3095
3124
  /**
3096
3125
  * Create a streaming text message draft
3097
3126
  *
@@ -4093,6 +4122,39 @@ export interface TelegramClient extends ITelegramClient {
4093
4122
  replyMedia(message: Message, ...params: ParametersSkip2<typeof sendMedia>): ReturnType<typeof sendMedia>;
4094
4123
  /** Send a media group in reply to a given message */
4095
4124
  replyMediaGroup(message: Message, ...params: ParametersSkip2<typeof sendMediaGroup>): ReturnType<typeof sendMediaGroup>;
4125
+ /**
4126
+ * Send a rich message
4127
+ *
4128
+ * **Available**: 👤 users only
4129
+ *
4130
+ * @param chatId ID of the chat, its username, phone or `"me"` or `"self"`
4131
+ * @param params Rich message contents and additional sending parameters
4132
+ */
4133
+ sendRichMessage(chatId: InputPeerLike, params: CommonSendParams & {
4134
+ content: InputRichMessage;
4135
+ /** Override the default random ID, for streaming drafts */
4136
+ randomId?: Long;
4137
+ /**
4138
+ * For bots: inline or reply markup or an instruction
4139
+ * to hide a reply keyboard or to force a reply.
4140
+ */
4141
+ replyMarkup?: ReplyMarkup;
4142
+ /**
4143
+ * Function that will be called after some part has been uploaded.
4144
+ *
4145
+ * @param id ID of the file being uploaded
4146
+ * @param uploaded Number of bytes already uploaded
4147
+ * @param total Total file size
4148
+ */
4149
+ progressCallback?: (id: string, uploaded: number, total: number) => void;
4150
+ /**
4151
+ * Cache for uploaded media, used to avoid re-uploading the same media multiple times.
4152
+ *
4153
+ * Pass a (potentially shared) {@link RichMediaUploadCache} to reuse media uploaded
4154
+ * by an earlier call (e.g. a streaming draft) instead of uploading it again.
4155
+ */
4156
+ uploadCache?: RichMediaUploadCache;
4157
+ }): Promise<Message>;
4096
4158
  /**
4097
4159
  * Send previously scheduled message(s)
4098
4160
  *
@@ -7,7 +7,9 @@ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WAR
7
7
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
8
8
  const utils = require("@fuman/utils");
9
9
  const fileId = require("@mtcute/file-id");
10
+ const delayGate = require("../../../network/delay-gate.cjs");
10
11
  const errors$1 = require("../../../types/errors.cjs");
12
+ const abortSignal = require("../../../utils/abort-signal.cjs");
11
13
  const peerUtils = require("../../../utils/peer-utils.cjs");
12
14
  const convertFileId = require("../../utils/convert-file-id.cjs");
13
15
  const fileUtils = require("../../utils/file-utils.cjs");
@@ -90,8 +92,17 @@ async function* downloadAsIterable(client, input, params) {
90
92
  let dcId = params?.dcId ?? normalized?.dcId;
91
93
  const primaryDcId = await client.getPrimaryDcId();
92
94
  if (!dcId) dcId = primaryDcId;
93
- const abortSignal = params?.abortSignal;
95
+ const stallTimeout = params?.stallTimeout;
96
+ const stallAbort = stallTimeout != null ? new AbortController() : void 0;
97
+ const abortSignal$1 = stallAbort ? params?.abortSignal ? abortSignal.combineAbortSignals(params.abortSignal, stallAbort.signal) : stallAbort.signal : params?.abortSignal;
94
98
  let ended = false;
99
+ let stallTimer;
100
+ const resetStallTimer = stallAbort && stallTimeout != null ? () => {
101
+ if (stallTimer) utils.timers.clearTimeout(stallTimer);
102
+ stallTimer = utils.timers.setTimeout(() => {
103
+ stallAbort.abort(new errors$1.MtTimeoutError(stallTimeout));
104
+ }, stallTimeout);
105
+ } : void 0;
95
106
  const partSizeKb = params?.partSize ?? (fileSize ? fileUtils.determinePartSize(fileSize) : 64);
96
107
  if (partSizeKb % 4 !== 0) {
97
108
  throw new errors$1.MtArgumentError(`Invalid part size: ${partSizeKb}. Must be divisible by 4.`);
@@ -120,6 +131,7 @@ async function* downloadAsIterable(client, input, params) {
120
131
  connectionKind = "download";
121
132
  }
122
133
  const poolSize = await client.getPoolSize(connectionKind, dcId);
134
+ const delayGate$1 = isSmall ? void 0 : new delayGate.DownloadDelayGate();
123
135
  client.log.debug(
124
136
  "Downloading file of size %d from dc %d using %s connection pool (pool size: %d)",
125
137
  limitBytes,
@@ -127,6 +139,44 @@ async function* downloadAsIterable(client, input, params) {
127
139
  connectionKind,
128
140
  poolSize
129
141
  );
142
+ const callPart = async (chunk) => {
143
+ while (true) {
144
+ try {
145
+ return await client.call(
146
+ {
147
+ _: isWeb ? "upload.getWebFile" : "upload.getFile",
148
+ // eslint-disable-next-line
149
+ location,
150
+ offset: offset + chunkSize * chunk,
151
+ limit: chunkSize
152
+ },
153
+ {
154
+ dcId,
155
+ kind: connectionKind,
156
+ maxRetryCount: Infinity,
157
+ // retry until explicitly aborted (or finished)
158
+ floodSleepThreshold: Infinity,
159
+ abortSignal: abortSignal$1
160
+ }
161
+ );
162
+ } catch (e) {
163
+ if (e instanceof DOMException && e.name === "AbortError") return void 0;
164
+ if (!innerTl.RpcError.is(e)) throw e;
165
+ if (e.is("FILE_MIGRATE_%d")) {
166
+ dcId = e.newDc;
167
+ continue;
168
+ } else if (e.is("FILEREF_UPGRADE_NEEDED")) {
169
+ throw new errors$1.MtUnsupportedError("File ref expired!");
170
+ } else if (e.is("MTPROTO_CLUSTER_INVALID") && dcId != null) {
171
+ client.log.debug("received cluster invalid error for dc %d, recreating dc", dcId);
172
+ await client.recreateDc(dcId);
173
+ continue;
174
+ } else {
175
+ throw e;
176
+ }
177
+ }
178
+ }
179
+ };
130
180
  const downloadChunk = async (chunk = nextWorkerChunkIdx++) => {
131
181
  let result;
132
182
  if (ended) {
@@ -136,40 +186,20 @@ async function* downloadAsIterable(client, input, params) {
136
186
  if (throttlePromise) {
137
187
  await throttlePromise;
138
188
  }
189
+ if (ended) {
190
+ return;
191
+ }
139
192
  try {
140
- result = await client.call(
141
- {
142
- _: isWeb ? "upload.getWebFile" : "upload.getFile",
143
- // eslint-disable-next-line
144
- location,
145
- offset: offset + chunkSize * chunk,
146
- limit: chunkSize
147
- },
148
- {
149
- dcId,
150
- kind: connectionKind,
151
- maxRetryCount: Infinity,
152
- // retry until explicitly aborted (or finished)
153
- floodSleepThreshold: Infinity,
154
- abortSignal
155
- }
156
- );
193
+ if (delayGate$1) await delayGate$1.wait(abortSignal$1);
194
+ result = await callPart(chunk);
157
195
  } catch (e) {
158
196
  if (e instanceof DOMException && e.name === "AbortError") return;
159
- if (!innerTl.RpcError.is(e)) throw e;
160
- if (e.is("FILE_MIGRATE_%d")) {
161
- dcId = e.newDc;
162
- return downloadChunk(chunk);
163
- } else if (e.is("FILEREF_UPGRADE_NEEDED")) {
164
- throw new errors$1.MtUnsupportedError("File ref expired!");
165
- } else if (e.is("MTPROTO_CLUSTER_INVALID") && dcId != null) {
166
- client.log.debug("received cluster invalid error for dc %d, recreating dc", dcId);
167
- await client.recreateDc(dcId);
168
- return downloadChunk(chunk);
169
- } else {
170
- throw e;
171
- }
197
+ throw e;
172
198
  }
199
+ if (!result) {
200
+ return;
201
+ }
202
+ resetStallTimer?.();
173
203
  if (result._ === "upload.fileCdnRedirect") {
174
204
  throw new errors$1.MtUnsupportedError("Received CDN redirect, which is not supported (yet)");
175
205
  }
@@ -189,6 +219,7 @@ async function* downloadAsIterable(client, input, params) {
189
219
  }
190
220
  };
191
221
  let error;
222
+ resetStallTimer?.();
192
223
  void Promise.all(Array.from({
193
224
  length: Math.min(poolSize * (isSmall ? 1 : REQUESTS_PER_CONNECTION), numChunks)
194
225
  }, downloadChunk)).catch((e) => {
@@ -199,27 +230,31 @@ async function* downloadAsIterable(client, input, params) {
199
230
  }).then(() => {
200
231
  client.log.debug("download workers finished");
201
232
  });
202
- abortSignal?.addEventListener("abort", () => {
233
+ abortSignal$1?.addEventListener("abort", () => {
203
234
  client.log.debug("download aborted");
204
- error = abortSignal.reason;
235
+ error = abortSignal$1.reason;
205
236
  ended = true;
206
237
  nextChunkCv.notify();
207
238
  });
208
239
  let position = offset;
209
- while (position < limitBytes) {
210
- await nextChunkCv.wait();
211
- if (error) throw error;
212
- while (nextChunkIdx in buffer) {
213
- const buf = buffer[nextChunkIdx];
214
- delete buffer[nextChunkIdx];
215
- position += buf.length;
216
- params?.progressCallback?.(position, limitBytes);
217
- yield buf;
218
- nextChunkIdx++;
219
- if (buf.length < chunkSize) {
220
- return;
240
+ try {
241
+ while (position < limitBytes) {
242
+ await nextChunkCv.wait();
243
+ if (error) throw error;
244
+ while (nextChunkIdx in buffer) {
245
+ const buf = buffer[nextChunkIdx];
246
+ delete buffer[nextChunkIdx];
247
+ position += buf.length;
248
+ params?.progressCallback?.(position, limitBytes);
249
+ yield buf;
250
+ nextChunkIdx++;
251
+ if (buf.length < chunkSize) {
252
+ return;
253
+ }
221
254
  }
222
255
  }
256
+ } finally {
257
+ if (stallTimer) utils.timers.clearTimeout(stallTimer);
223
258
  }
224
259
  }
225
260
  exports._normalizeFileDownloadLocation = _normalizeFileDownloadLocation;
@@ -1,6 +1,8 @@
1
- import { ConditionVariable } from "@fuman/utils";
1
+ import { ConditionVariable, timers } from "@fuman/utils";
2
2
  import { parseFileId } from "@mtcute/file-id";
3
- import { MtArgumentError, MtUnsupportedError } from "../../../types/errors.js";
3
+ import { DownloadDelayGate } from "../../../network/delay-gate.js";
4
+ import { MtArgumentError, MtTimeoutError, MtUnsupportedError } from "../../../types/errors.js";
5
+ import { combineAbortSignals } from "../../../utils/abort-signal.js";
4
6
  import { toggleChannelIdMark } from "../../../utils/peer-utils.js";
5
7
  import { fileIdToInputWebFileLocation, fileIdToInputFileLocation } from "../../utils/convert-file-id.js";
6
8
  import { determinePartSize } from "../../utils/file-utils.js";
@@ -83,8 +85,17 @@ async function* downloadAsIterable(client, input, params) {
83
85
  let dcId = params?.dcId ?? normalized?.dcId;
84
86
  const primaryDcId = await client.getPrimaryDcId();
85
87
  if (!dcId) dcId = primaryDcId;
86
- const abortSignal = params?.abortSignal;
88
+ const stallTimeout = params?.stallTimeout;
89
+ const stallAbort = stallTimeout != null ? new AbortController() : void 0;
90
+ const abortSignal = stallAbort ? params?.abortSignal ? combineAbortSignals(params.abortSignal, stallAbort.signal) : stallAbort.signal : params?.abortSignal;
87
91
  let ended = false;
92
+ let stallTimer;
93
+ const resetStallTimer = stallAbort && stallTimeout != null ? () => {
94
+ if (stallTimer) timers.clearTimeout(stallTimer);
95
+ stallTimer = timers.setTimeout(() => {
96
+ stallAbort.abort(new MtTimeoutError(stallTimeout));
97
+ }, stallTimeout);
98
+ } : void 0;
88
99
  const partSizeKb = params?.partSize ?? (fileSize ? determinePartSize(fileSize) : 64);
89
100
  if (partSizeKb % 4 !== 0) {
90
101
  throw new MtArgumentError(`Invalid part size: ${partSizeKb}. Must be divisible by 4.`);
@@ -113,6 +124,7 @@ async function* downloadAsIterable(client, input, params) {
113
124
  connectionKind = "download";
114
125
  }
115
126
  const poolSize = await client.getPoolSize(connectionKind, dcId);
127
+ const delayGate = isSmall ? void 0 : new DownloadDelayGate();
116
128
  client.log.debug(
117
129
  "Downloading file of size %d from dc %d using %s connection pool (pool size: %d)",
118
130
  limitBytes,
@@ -120,6 +132,44 @@ async function* downloadAsIterable(client, input, params) {
120
132
  connectionKind,
121
133
  poolSize
122
134
  );
135
+ const callPart = async (chunk) => {
136
+ while (true) {
137
+ try {
138
+ return await client.call(
139
+ {
140
+ _: isWeb ? "upload.getWebFile" : "upload.getFile",
141
+ // eslint-disable-next-line
142
+ location,
143
+ offset: offset + chunkSize * chunk,
144
+ limit: chunkSize
145
+ },
146
+ {
147
+ dcId,
148
+ kind: connectionKind,
149
+ maxRetryCount: Infinity,
150
+ // retry until explicitly aborted (or finished)
151
+ floodSleepThreshold: Infinity,
152
+ abortSignal
153
+ }
154
+ );
155
+ } catch (e) {
156
+ if (e instanceof DOMException && e.name === "AbortError") return void 0;
157
+ if (!RpcError.is(e)) throw e;
158
+ if (e.is("FILE_MIGRATE_%d")) {
159
+ dcId = e.newDc;
160
+ continue;
161
+ } else if (e.is("FILEREF_UPGRADE_NEEDED")) {
162
+ throw new MtUnsupportedError("File ref expired!");
163
+ } else if (e.is("MTPROTO_CLUSTER_INVALID") && dcId != null) {
164
+ client.log.debug("received cluster invalid error for dc %d, recreating dc", dcId);
165
+ await client.recreateDc(dcId);
166
+ continue;
167
+ } else {
168
+ throw e;
169
+ }
170
+ }
171
+ }
172
+ };
123
173
  const downloadChunk = async (chunk = nextWorkerChunkIdx++) => {
124
174
  let result;
125
175
  if (ended) {
@@ -129,40 +179,20 @@ async function* downloadAsIterable(client, input, params) {
129
179
  if (throttlePromise) {
130
180
  await throttlePromise;
131
181
  }
182
+ if (ended) {
183
+ return;
184
+ }
132
185
  try {
133
- result = await client.call(
134
- {
135
- _: isWeb ? "upload.getWebFile" : "upload.getFile",
136
- // eslint-disable-next-line
137
- location,
138
- offset: offset + chunkSize * chunk,
139
- limit: chunkSize
140
- },
141
- {
142
- dcId,
143
- kind: connectionKind,
144
- maxRetryCount: Infinity,
145
- // retry until explicitly aborted (or finished)
146
- floodSleepThreshold: Infinity,
147
- abortSignal
148
- }
149
- );
186
+ if (delayGate) await delayGate.wait(abortSignal);
187
+ result = await callPart(chunk);
150
188
  } catch (e) {
151
189
  if (e instanceof DOMException && e.name === "AbortError") return;
152
- if (!RpcError.is(e)) throw e;
153
- if (e.is("FILE_MIGRATE_%d")) {
154
- dcId = e.newDc;
155
- return downloadChunk(chunk);
156
- } else if (e.is("FILEREF_UPGRADE_NEEDED")) {
157
- throw new MtUnsupportedError("File ref expired!");
158
- } else if (e.is("MTPROTO_CLUSTER_INVALID") && dcId != null) {
159
- client.log.debug("received cluster invalid error for dc %d, recreating dc", dcId);
160
- await client.recreateDc(dcId);
161
- return downloadChunk(chunk);
162
- } else {
163
- throw e;
164
- }
190
+ throw e;
165
191
  }
192
+ if (!result) {
193
+ return;
194
+ }
195
+ resetStallTimer?.();
166
196
  if (result._ === "upload.fileCdnRedirect") {
167
197
  throw new MtUnsupportedError("Received CDN redirect, which is not supported (yet)");
168
198
  }
@@ -182,6 +212,7 @@ async function* downloadAsIterable(client, input, params) {
182
212
  }
183
213
  };
184
214
  let error;
215
+ resetStallTimer?.();
185
216
  void Promise.all(Array.from({
186
217
  length: Math.min(poolSize * (isSmall ? 1 : REQUESTS_PER_CONNECTION), numChunks)
187
218
  }, downloadChunk)).catch((e) => {
@@ -199,20 +230,24 @@ async function* downloadAsIterable(client, input, params) {
199
230
  nextChunkCv.notify();
200
231
  });
201
232
  let position = offset;
202
- while (position < limitBytes) {
203
- await nextChunkCv.wait();
204
- if (error) throw error;
205
- while (nextChunkIdx in buffer) {
206
- const buf = buffer[nextChunkIdx];
207
- delete buffer[nextChunkIdx];
208
- position += buf.length;
209
- params?.progressCallback?.(position, limitBytes);
210
- yield buf;
211
- nextChunkIdx++;
212
- if (buf.length < chunkSize) {
213
- return;
233
+ try {
234
+ while (position < limitBytes) {
235
+ await nextChunkCv.wait();
236
+ if (error) throw error;
237
+ while (nextChunkIdx in buffer) {
238
+ const buf = buffer[nextChunkIdx];
239
+ delete buffer[nextChunkIdx];
240
+ position += buf.length;
241
+ params?.progressCallback?.(position, limitBytes);
242
+ yield buf;
243
+ nextChunkIdx++;
244
+ if (buf.length < chunkSize) {
245
+ return;
246
+ }
214
247
  }
215
248
  }
249
+ } finally {
250
+ if (stallTimer) timers.clearTimeout(stallTimer);
216
251
  }
217
252
  }
218
253
  export {
@@ -29,6 +29,14 @@ async function _normalizeInputMedia(client, media, params = {}, uploadMedia = fa
29
29
  }
30
30
  return media;
31
31
  }
32
+ if (innerTl.isAnyInputPhoto(media)) {
33
+ typeAssertions.assertTypeIs("normalizeInputMedia (@ photo)", media, "inputPhoto");
34
+ return { _: "inputMediaPhoto", id: media };
35
+ }
36
+ if (innerTl.isAnyInputDocument(media)) {
37
+ typeAssertions.assertTypeIs("normalizeInputMedia (@ document)", media, "inputDocument");
38
+ return { _: "inputMediaDocument", id: media };
39
+ }
32
40
  if (media.type === "venue") {
33
41
  return {
34
42
  _: "inputMediaVenue",
@@ -275,7 +283,7 @@ async function _normalizeInputMedia(client, media, params = {}, uploadMedia = fa
275
283
  fileReference: res.photo.fileReference
276
284
  },
277
285
  ttlSeconds: media.ttlSeconds,
278
- spoiler: media.type === "video" && media.spoiler,
286
+ spoiler: "spoiler" in media ? media.spoiler : false,
279
287
  livePhoto: Boolean(livePhotoVideo),
280
288
  video: livePhotoVideo
281
289
  };