k2-im 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat-kit-pinia.d.ts +43 -2
- package/dist/chat-kit.d.ts +43 -2
- package/dist/index.d.ts +44 -3
- package/dist/modules/im-core/src/connection/client-activity.js +1 -0
- package/dist/modules/im-core/src/connection/connection-manager.js +1 -1
- package/dist/modules/im-core/src/message-flow/receive/channel-receive-handlers.js +1 -1
- package/dist/modules/im-core/src/outbox/outbox-manager.js +1 -1
- package/dist/modules/im-protocol/src/protobuf/gen/im.login_pb.js +1 -1
- package/dist/modules/im-protocol/src/protobuf/gen/im.pub_pb.js +1 -1
- package/dist/modules/im-protocol/src/protobuf/registry.js +1 -1
- package/dist/modules/im-sdk/src/create-im-client.js +1 -1
- package/dist/modules/im-sdk/src/runtime/session-runtime.js +1 -1
- package/dist/sdk.d.ts +44 -3
- package/package.json +1 -1
package/dist/chat-kit-pinia.d.ts
CHANGED
|
@@ -1600,6 +1600,45 @@ interface ImChannelJoinApplicationPort {
|
|
|
1600
1600
|
ignoreJoinApplication: (applicationId: string) => Promise<void>;
|
|
1601
1601
|
}
|
|
1602
1602
|
|
|
1603
|
+
/** 宿主提供的页面可见状态;Core 不读取或监听页面资源。 */
|
|
1604
|
+
type ImClientVisibility = 'visible' | 'hidden';
|
|
1605
|
+
/** 只记录上报结果,不含登录凭据或推送订阅。synced 仅表示收到匹配的服务端确认。 */
|
|
1606
|
+
interface ImClientActivitySnapshot {
|
|
1607
|
+
/** idle 未启用;pending 等待认证;syncing 等待服务端回复;synced 已确认;error 失败;disposed 已释放。 */
|
|
1608
|
+
status: 'idle' | 'pending' | 'syncing' | 'synced' | 'error' | 'disposed';
|
|
1609
|
+
/** 最近一次需要报告的页面状态;未启用或已释放时为空。 */
|
|
1610
|
+
visibility?: ImClientVisibility;
|
|
1611
|
+
/** 本连接内的上报序号,使用字符串避免 uint64 丢失精度。 */
|
|
1612
|
+
sequence?: string;
|
|
1613
|
+
/** 成功回复给出的前台有效秒数;不表示该页面接下来一直可见。 */
|
|
1614
|
+
foregroundTtlSeconds?: number;
|
|
1615
|
+
/** 成功回复中的服务端毫秒时间,用字符串保留 uint64 精度。 */
|
|
1616
|
+
serverTimeMs?: string;
|
|
1617
|
+
/** 仅 error 状态存在:等待超时、回复无效、服务端拒绝或发送失败。 */
|
|
1618
|
+
error?: 'timeout' | 'invalid-ack' | 'server-rejected' | 'send-failed';
|
|
1619
|
+
/** 仅服务端明确拒绝时提供的错误编号。 */
|
|
1620
|
+
serverCode?: number;
|
|
1621
|
+
}
|
|
1622
|
+
/** 页面状态上报默认关闭;宿主明确设置状态后,连接恢复与前台心跳才会自动上报。 */
|
|
1623
|
+
interface ImClientActivityApi {
|
|
1624
|
+
/**
|
|
1625
|
+
* 设置需要报告的页面状态;未认证时保存,认证完成后发送。
|
|
1626
|
+
* 账号须为当前账号的正整数编号;账号或状态无效、实例已释放时同步抛错。
|
|
1627
|
+
* @example
|
|
1628
|
+
* client.activity.setVisibility({ userId: '123', visibility: 'hidden' });
|
|
1629
|
+
*/
|
|
1630
|
+
setVisibility: (input: {
|
|
1631
|
+
userId: string;
|
|
1632
|
+
visibility: ImClientVisibility;
|
|
1633
|
+
}) => void;
|
|
1634
|
+
/** 停止自动报告并取消待处理请求;这不会向服务端发送后台状态。 */
|
|
1635
|
+
clear: () => void;
|
|
1636
|
+
/** 读取当前报告结果的副本,修改返回值不会改变 SDK 状态。 */
|
|
1637
|
+
snapshot: () => ImClientActivitySnapshot;
|
|
1638
|
+
/** 立即提供当前结果,之后通知变化;返回停止监听的函数。监听器异常通过 SDK 错误事件报告。 */
|
|
1639
|
+
subscribe: (listener: (snapshot: ImClientActivitySnapshot) => void) => () => void;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1603
1642
|
interface ImLoginContext {
|
|
1604
1643
|
userId: string;
|
|
1605
1644
|
token: string;
|
|
@@ -3215,9 +3254,9 @@ interface TextMessageOptions {
|
|
|
3215
3254
|
mentions?: readonly MentionInput[];
|
|
3216
3255
|
replyToMessageId?: string;
|
|
3217
3256
|
}
|
|
3218
|
-
/**
|
|
3257
|
+
/** 可主动分享的名片。未知 wire 类别只保留接收,不能放进发送入参。 */
|
|
3219
3258
|
type ContactCardInput = Omit<ImContactBody, 'kind' | 'rawKind'> & {
|
|
3220
|
-
kind: Extract<ImContactBody['kind'], 'individual' | 'group' | 'channel'>;
|
|
3259
|
+
kind: Extract<ImContactBody['kind'], 'individual' | 'group' | 'channel' | 'robot'>;
|
|
3221
3260
|
};
|
|
3222
3261
|
/** 名片发送附加数据;回复关系与其它可发送消息使用同一稳定消息 id。 */
|
|
3223
3262
|
interface ContactMessageOptions {
|
|
@@ -6712,6 +6751,8 @@ interface AdvancedConversationsApi extends ImConversationsApi, ImConversationBac
|
|
|
6712
6751
|
interface ImProductClient {
|
|
6713
6752
|
/** 当前设备推送订阅的服务端绑定与同步状态。 */
|
|
6714
6753
|
readonly push: ImPushApi;
|
|
6754
|
+
/** 宿主显式报告页面可见状态;默认未启用,不影响未接入此协议的客户端。 */
|
|
6755
|
+
readonly activity: ImClientActivityApi;
|
|
6715
6756
|
readonly session: ImSessionApi;
|
|
6716
6757
|
readonly capabilities: ImConversationCapabilitiesApi;
|
|
6717
6758
|
readonly conversations: ImConversationListApi;
|
package/dist/chat-kit.d.ts
CHANGED
|
@@ -1597,6 +1597,45 @@ interface ImChannelJoinApplicationPort {
|
|
|
1597
1597
|
ignoreJoinApplication: (applicationId: string) => Promise<void>;
|
|
1598
1598
|
}
|
|
1599
1599
|
|
|
1600
|
+
/** 宿主提供的页面可见状态;Core 不读取或监听页面资源。 */
|
|
1601
|
+
type ImClientVisibility = 'visible' | 'hidden';
|
|
1602
|
+
/** 只记录上报结果,不含登录凭据或推送订阅。synced 仅表示收到匹配的服务端确认。 */
|
|
1603
|
+
interface ImClientActivitySnapshot {
|
|
1604
|
+
/** idle 未启用;pending 等待认证;syncing 等待服务端回复;synced 已确认;error 失败;disposed 已释放。 */
|
|
1605
|
+
status: 'idle' | 'pending' | 'syncing' | 'synced' | 'error' | 'disposed';
|
|
1606
|
+
/** 最近一次需要报告的页面状态;未启用或已释放时为空。 */
|
|
1607
|
+
visibility?: ImClientVisibility;
|
|
1608
|
+
/** 本连接内的上报序号,使用字符串避免 uint64 丢失精度。 */
|
|
1609
|
+
sequence?: string;
|
|
1610
|
+
/** 成功回复给出的前台有效秒数;不表示该页面接下来一直可见。 */
|
|
1611
|
+
foregroundTtlSeconds?: number;
|
|
1612
|
+
/** 成功回复中的服务端毫秒时间,用字符串保留 uint64 精度。 */
|
|
1613
|
+
serverTimeMs?: string;
|
|
1614
|
+
/** 仅 error 状态存在:等待超时、回复无效、服务端拒绝或发送失败。 */
|
|
1615
|
+
error?: 'timeout' | 'invalid-ack' | 'server-rejected' | 'send-failed';
|
|
1616
|
+
/** 仅服务端明确拒绝时提供的错误编号。 */
|
|
1617
|
+
serverCode?: number;
|
|
1618
|
+
}
|
|
1619
|
+
/** 页面状态上报默认关闭;宿主明确设置状态后,连接恢复与前台心跳才会自动上报。 */
|
|
1620
|
+
interface ImClientActivityApi {
|
|
1621
|
+
/**
|
|
1622
|
+
* 设置需要报告的页面状态;未认证时保存,认证完成后发送。
|
|
1623
|
+
* 账号须为当前账号的正整数编号;账号或状态无效、实例已释放时同步抛错。
|
|
1624
|
+
* @example
|
|
1625
|
+
* client.activity.setVisibility({ userId: '123', visibility: 'hidden' });
|
|
1626
|
+
*/
|
|
1627
|
+
setVisibility: (input: {
|
|
1628
|
+
userId: string;
|
|
1629
|
+
visibility: ImClientVisibility;
|
|
1630
|
+
}) => void;
|
|
1631
|
+
/** 停止自动报告并取消待处理请求;这不会向服务端发送后台状态。 */
|
|
1632
|
+
clear: () => void;
|
|
1633
|
+
/** 读取当前报告结果的副本,修改返回值不会改变 SDK 状态。 */
|
|
1634
|
+
snapshot: () => ImClientActivitySnapshot;
|
|
1635
|
+
/** 立即提供当前结果,之后通知变化;返回停止监听的函数。监听器异常通过 SDK 错误事件报告。 */
|
|
1636
|
+
subscribe: (listener: (snapshot: ImClientActivitySnapshot) => void) => () => void;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1600
1639
|
interface ImLoginContext {
|
|
1601
1640
|
userId: string;
|
|
1602
1641
|
token: string;
|
|
@@ -3316,9 +3355,9 @@ interface TextMessageOptions {
|
|
|
3316
3355
|
mentions?: readonly MentionInput[];
|
|
3317
3356
|
replyToMessageId?: string;
|
|
3318
3357
|
}
|
|
3319
|
-
/**
|
|
3358
|
+
/** 可主动分享的名片。未知 wire 类别只保留接收,不能放进发送入参。 */
|
|
3320
3359
|
type ContactCardInput = Omit<ImContactBody, 'kind' | 'rawKind'> & {
|
|
3321
|
-
kind: Extract<ImContactBody['kind'], 'individual' | 'group' | 'channel'>;
|
|
3360
|
+
kind: Extract<ImContactBody['kind'], 'individual' | 'group' | 'channel' | 'robot'>;
|
|
3322
3361
|
};
|
|
3323
3362
|
/** 名片发送附加数据;回复关系与其它可发送消息使用同一稳定消息 id。 */
|
|
3324
3363
|
interface ContactMessageOptions {
|
|
@@ -6822,6 +6861,8 @@ interface AdvancedConversationsApi extends ImConversationsApi, ImConversationBac
|
|
|
6822
6861
|
interface ImProductClient {
|
|
6823
6862
|
/** 当前设备推送订阅的服务端绑定与同步状态。 */
|
|
6824
6863
|
readonly push: ImPushApi;
|
|
6864
|
+
/** 宿主显式报告页面可见状态;默认未启用,不影响未接入此协议的客户端。 */
|
|
6865
|
+
readonly activity: ImClientActivityApi;
|
|
6825
6866
|
readonly session: ImSessionApi;
|
|
6826
6867
|
readonly capabilities: ImConversationCapabilitiesApi;
|
|
6827
6868
|
readonly conversations: ImConversationListApi;
|
package/dist/index.d.ts
CHANGED
|
@@ -1638,6 +1638,45 @@ interface ImChannelJoinApplicationPort {
|
|
|
1638
1638
|
ignoreJoinApplication: (applicationId: string) => Promise<void>;
|
|
1639
1639
|
}
|
|
1640
1640
|
|
|
1641
|
+
/** 宿主提供的页面可见状态;Core 不读取或监听页面资源。 */
|
|
1642
|
+
type ImClientVisibility = 'visible' | 'hidden';
|
|
1643
|
+
/** 只记录上报结果,不含登录凭据或推送订阅。synced 仅表示收到匹配的服务端确认。 */
|
|
1644
|
+
interface ImClientActivitySnapshot {
|
|
1645
|
+
/** idle 未启用;pending 等待认证;syncing 等待服务端回复;synced 已确认;error 失败;disposed 已释放。 */
|
|
1646
|
+
status: 'idle' | 'pending' | 'syncing' | 'synced' | 'error' | 'disposed';
|
|
1647
|
+
/** 最近一次需要报告的页面状态;未启用或已释放时为空。 */
|
|
1648
|
+
visibility?: ImClientVisibility;
|
|
1649
|
+
/** 本连接内的上报序号,使用字符串避免 uint64 丢失精度。 */
|
|
1650
|
+
sequence?: string;
|
|
1651
|
+
/** 成功回复给出的前台有效秒数;不表示该页面接下来一直可见。 */
|
|
1652
|
+
foregroundTtlSeconds?: number;
|
|
1653
|
+
/** 成功回复中的服务端毫秒时间,用字符串保留 uint64 精度。 */
|
|
1654
|
+
serverTimeMs?: string;
|
|
1655
|
+
/** 仅 error 状态存在:等待超时、回复无效、服务端拒绝或发送失败。 */
|
|
1656
|
+
error?: 'timeout' | 'invalid-ack' | 'server-rejected' | 'send-failed';
|
|
1657
|
+
/** 仅服务端明确拒绝时提供的错误编号。 */
|
|
1658
|
+
serverCode?: number;
|
|
1659
|
+
}
|
|
1660
|
+
/** 页面状态上报默认关闭;宿主明确设置状态后,连接恢复与前台心跳才会自动上报。 */
|
|
1661
|
+
interface ImClientActivityApi {
|
|
1662
|
+
/**
|
|
1663
|
+
* 设置需要报告的页面状态;未认证时保存,认证完成后发送。
|
|
1664
|
+
* 账号须为当前账号的正整数编号;账号或状态无效、实例已释放时同步抛错。
|
|
1665
|
+
* @example
|
|
1666
|
+
* client.activity.setVisibility({ userId: '123', visibility: 'hidden' });
|
|
1667
|
+
*/
|
|
1668
|
+
setVisibility: (input: {
|
|
1669
|
+
userId: string;
|
|
1670
|
+
visibility: ImClientVisibility;
|
|
1671
|
+
}) => void;
|
|
1672
|
+
/** 停止自动报告并取消待处理请求;这不会向服务端发送后台状态。 */
|
|
1673
|
+
clear: () => void;
|
|
1674
|
+
/** 读取当前报告结果的副本,修改返回值不会改变 SDK 状态。 */
|
|
1675
|
+
snapshot: () => ImClientActivitySnapshot;
|
|
1676
|
+
/** 立即提供当前结果,之后通知变化;返回停止监听的函数。监听器异常通过 SDK 错误事件报告。 */
|
|
1677
|
+
subscribe: (listener: (snapshot: ImClientActivitySnapshot) => void) => () => void;
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1641
1680
|
interface ImLoginContext {
|
|
1642
1681
|
userId: string;
|
|
1643
1682
|
token: string;
|
|
@@ -3849,9 +3888,9 @@ interface TextMessageOptions {
|
|
|
3849
3888
|
mentions?: readonly MentionInput[];
|
|
3850
3889
|
replyToMessageId?: string;
|
|
3851
3890
|
}
|
|
3852
|
-
/**
|
|
3891
|
+
/** 可主动分享的名片。未知 wire 类别只保留接收,不能放进发送入参。 */
|
|
3853
3892
|
type ContactCardInput = Omit<ImContactBody, 'kind' | 'rawKind'> & {
|
|
3854
|
-
kind: Extract<ImContactBody['kind'], 'individual' | 'group' | 'channel'>;
|
|
3893
|
+
kind: Extract<ImContactBody['kind'], 'individual' | 'group' | 'channel' | 'robot'>;
|
|
3855
3894
|
};
|
|
3856
3895
|
/** 名片发送附加数据;回复关系与其它可发送消息使用同一稳定消息 id。 */
|
|
3857
3896
|
interface ContactMessageOptions {
|
|
@@ -7411,6 +7450,8 @@ interface AdvancedConversationsApi extends ImConversationsApi, ImConversationBac
|
|
|
7411
7450
|
interface ImProductClient {
|
|
7412
7451
|
/** 当前设备推送订阅的服务端绑定与同步状态。 */
|
|
7413
7452
|
readonly push: ImPushApi;
|
|
7453
|
+
/** 宿主显式报告页面可见状态;默认未启用,不影响未接入此协议的客户端。 */
|
|
7454
|
+
readonly activity: ImClientActivityApi;
|
|
7414
7455
|
readonly session: ImSessionApi;
|
|
7415
7456
|
readonly capabilities: ImConversationCapabilitiesApi;
|
|
7416
7457
|
readonly conversations: ImConversationListApi;
|
|
@@ -10945,4 +10986,4 @@ declare function resampleWaveform(data: readonly number[], targetCount: number):
|
|
|
10945
10986
|
declare function placeholderWaveform(seed: string, count: number): number[];
|
|
10946
10987
|
|
|
10947
10988
|
export { DEFAULT_EMOJI_ASSET_BASE, DEFAULT_LOADING_MINIMUM_VISIBLE_MS, DEFAULT_LOADING_SHOW_DELAY_MS, DEFAULT_LOCALE, EDIT_WINDOW_MS, EMOJI_CATALOG, EMOJI_GAME_DICE_STABLE_KEY, EMOJI_GAME_RPS_STABLE_KEY, EMOJI_TOKEN_RE, IMAGE_MESSAGE_ACCEPT, IM_CHAT_FONT_SCALES, IM_DIAGNOSTIC_CATEGORIES, IM_EMOJI_CATALOG, ImPinnedMessageOperationError, MAX_BATCH_FILES, MAX_RECENT_EMOJI_COUNT, MEDIA_ALBUM_CAPTION_MAX_LENGTH, MEDIA_ALBUM_MAX_ITEMS, MINI_PROGRAM_GAME_PREVIEW_FALLBACK_HEIGHT, MINI_PROGRAM_GAME_PREVIEW_FALLBACK_WIDTH, MINI_PROGRAM_LANG_NUMBERS, MediaTransferError, REACTION_SUPPORTED_CONTENT_TYPES, SPIKE_STEP, UNICODE_EMOJI_CATALOG, blockReasonForChannelSession, blockReasonForChannelState, blockReasonForGroupState, blockReasonForSession, buildSessionFavoritePlainBody, calculateMediaBox, canCopyMessageImage, canEditMessage, canPinChannelMessage, canPinGroupMessage, canPinMessage, canPromoteMediaPresentationSource, canReactToMessage, canRecallMessage, canTransmit, canTransmitByType, canTransmitContent, cancelMediaUpload, captureRuntimeClientOperation, captureRuntimeOperation, channelMiniProgramRelKey, classifyGifFile, classifyMediaFile, classifyStickerImageType, countUnreadConversations, createChatRuntime, createConversationPrefetchController, createDelayedLoadingIndicator, createEmojiMatcher, createFaceToFaceGroupQrPayload, createImClient, createImConsoleDiagnosticSink, createImDiagnosticMemoryBuffer, createImI18n, createImResourceUploader, createImTextSearchMatcher, createLinkMatcher, createMessageImageCopySource, createNewMessageBadgeController, createSdkDiagnosticWriter, createThreadItems, createVoicePlayer, createVoiceRecordingSession, csvIncludes, decideChannelMiniProgramRelOpen, decideConversationAction, decideMemberTargetAction, decideMessageAction, detectVoiceCapabilities, emojiAssetUrl, emojiUrlByCode, extractSearchText, fetchConversationFileBatch, fetchConversationImageBatch, fetchConversationMessageBatch, fetchConversationVideoBatch, fetchConversationVoiceBatch, fetchNextConversationSearchBatch, formatChatDateSeparator, formatConversationDisplayTime, formatConversationUnreadBadge, formatFailure, formatFileSize, formatLastMessageSummary, formatMediaDuration, formatMediaPlaceholder, formatMentionAll, formatServiceText, formatSystemMessage, forward_service as forwardService, getFileExtension, getImTextSearchInitial, getImTimeCatalog, getLocalDayKey, getMessageCopyImageUrl, getMessageCopyText, hasEmojiCandidate, hasLinkCandidate, highlightSegments, isGifFile, isMessageLocateScrollProtected, isMessageTailChangeFromOlderWindowTrim, isMessageViewportMeasurable, isMessageVisibleForNewMessageBadge, isMiniProgramShowTypeOpenable, isPinnedMessageProtected, isSupportedImageFile, isVoiceStorageConfigured, loadOlderUntilBoundary, mediaBatchBudgetBytes, media_service as mediaService, mediaTransferErrorCodeOf, message_service as messageService, migrateImCachePrefix, normalizeImLocale, normalizeLinkHref, normalizeMediaUploadCredentials, parseSessionFavoriteAlbumItems, parseSessionFavoriteFileItems, parseUnicodeEmojiCode, pinnedMessage_service as pinnedMessageService, placeholderWaveform, prependRecentEmoji, profile_service as profileService, read_service as readService, refreshPrependMessageAnchorPosition, registerImCatalogOverrides, replaceInterruptedMediaFile, requiresConversationEncryption, requiresForwardTypeConfirmation, resampleWaveform, resetImCatalogOverrides, resolveBestMediaPresentationSource, resolveCenteredMessageScrollTop, resolveChannelAccess, resolveChannelMemberAvatarUrl, resolveChannelMemberDisplayName, resolveChannelMiniProgramRelIcon, resolveChannelMiniProgramRelName, resolveChannelMiniProgramRelOpenSurface, resolveChannelMiniProgramRelUrl, resolveChannelPinnedGameCopy, resolveConversationListPresentation, resolveDisplayTimestamp, resolveEmojiToken, resolveFriendDisplayName, resolveImEmojiToken, resolveImProfileAccessDestination, resolveImThreadActiveDate, resolveMediaAlbumSendContentType, resolveMediaPresentation, resolveMediaTransferPresentation, resolveMemberDisplayName, resolveMessageBodyKind, resolveMessageNotificationDecision, resolveMessageSearchPreview, resolveMessageTimelineTimestamp, resolveMiniProgramFloatLinkUrl, resolveMiniProgramGamePreviewLayout, resolveMiniProgramOpenUrl, resolvePrependMessageAnchor, resolvePrependMessageAnchorAdjustment, resolvePrependMessageAnchorPosition, resolvePublicNickname, resolveQuotedMessagePresentation, resolveSenderAvatarUrl, resolveSessionFavoriteAlbumCaption, resolveSessionFavoriteAlbumItemPreviewUrl, resolveSessionFavoriteKindFromMessage, resolveStandaloneEmojiMessage, resolveSurvivingMessageAnchorAdjustment, resolveTextSegments, resolveUnicodeEmoji, resolveVisibleChannelMiniProgramRels, resolveVisibleMessageAnchorPositions, retryMessage, runMediaSendBatch, sendAsFilesBatch, sendBlockReasonForDecision, sendMediaAlbum, sendMediaFile, sendMediaFilesBatch, sendText, sendVoice, shouldCompleteInitialViewport, shouldFillInitialHistoryViewport, shouldFollowIncomingMessage, shouldLoadNewerHistoryPage, shouldPrefetchOlderHistory, shouldRestoreMessageViewportFocus, shouldShowChatDateSeparator, shouldTrackRemoteMessageForBadge, sortChannelMiniProgramFloatingItems, sortSessions, spikeCountForDuration, sumSessionsUnread, supportsConversationMention, unicodeEmojiTextFromCode, voiceErrorCodeOf };
|
|
10948
|
-
export type { ApplySessionResult, BrowseMessagesInput, CanPinMessageInput, CapabilityAvailability, CapabilityDecision, CapabilityReason, CenteredMessageScrollInput, ChannelAccessSnapshot, ChannelBaseSessionState, ChannelConversationCapabilities, ChannelConversationMessageApi, ChannelJoinApplication, ChannelJoinApplicationNotification, ChannelJoinApplicationPage, ChannelMember, ChannelMemberPage, ChannelMentionMember, ChannelMentionMemberPage, ChannelMiniProgramOpenGame, ChannelMiniProgramRel, ChannelMiniProgramRelConfigType, ChannelMiniProgramRelOpenDecision, ChannelMiniProgramRelOpenSurface, ChannelMuteReason, ChannelPermissionSet, ChannelProfile, ChannelRole, ChannelSessionState, ChatMediaMessageRef, ChatProfileAdapter, ChatRuntime, ChatRuntimeCredentials, ChatRuntimeFactories, ChatRuntimeHostDeps, ChatRuntimeOpResult, ContactCardInput, ContactMessageOptions, ConversationBackgroundPreset, ConversationBackgroundSelection, ConversationCapabilityAction, ConversationCapabilitySnapshot, ConversationDraft, ConversationDraftApi, ConversationEntryUnreadNavigation, ConversationEntryUnreadSnapshot, ConversationHandle, ConversationHandleSnapshot, ConversationInitialPosition, ConversationLastMessageSummary, ConversationListItem, ConversationListMention, ConversationListPresentation, ConversationListPresentationLabels, ConversationListPresentationOptions, ConversationListPreviewMediaKind, ConversationListPreviewSegment, ConversationMessageApi, ConversationOpenOptions, ConversationPrefetchController, ConversationPrefetchControllerOptions, ConversationPrefetchOptions, ConversationPrefetchResult, ConversationRef, ConversationSearchCategory, ConversationSearchPage, ConversationSearchResult, ConversationSystemSummary, ConversationType, CreateThreadItemsInput, CustomerServiceConversationCapabilities, DelayedLoadingIndicator, DelayedLoadingIndicatorOptions, DirectConversationCapabilities, DirectConversationMessageApi, DraftInput, EditTextOptions, EmojiEntry, EmojiRecentItem, EmojiSegment, ExpressionMessageOptions, FileMessageOptions, FormatFailureContext, FormatLastMessageContext, FormatMediaPlaceholderContext, FormatServiceTextContext, FormatSystemMessageContext, FormatTimeDisplayContext, ForwardCommandHooks, ForwardFailReason, ForwardItemStatus, ForwardMessageFailure, ForwardMessagesInput, ForwardMessagesResult, ForwardTarget, ForwardedMessageRef, GameMessageOptions, GifFileClassification, GifMessageOptions, GiftMessageOptions, GroupConversationCapabilities, GroupConversationMessageApi, GroupMemberItem, GroupProfile, HighlightSegment, ImAppearanceSettingsApi, ImApplicationItem, ImApplicationRef, ImApplicationsApi, ImAuthIssue, ImAuthProvider, ImBlockedContact, ImCacheOptions, ImCachePrefixMigrationContext, ImCachePrefixMigrator, ImCallKind, ImCallOutcome, ImCallRecordBody, ImCatalog, ImCatalogOverrides, ImChannelConversationAccessSnapshot, ImChannelMemberPresentation, ImChannelMentionApi, ImChannelMentionPresentation, ImChannelMiniProgramRel, ImChannelPermissions, ImChannelPinnedMessage, ImChannelProfile, ImChannelProfilePresentation, ImChannelRole, ImChannelState, ImChannelsApi, ImChatFontScale, ImClientOptions, ImConnectionState, ImContactBody, ImContactKind, ImContactProfile, ImContactRelationship, ImContactRemarkPhone, ImContactSearchResult, ImContactsApi, ImConversationBackgroundApi, ImConversationCapabilitiesApi, ImConversationListApi, ImConversationListSnapshot, ImConversationListState, ImConversationSearchApi, ImCoreApiOptions, ImCreateChannelInput, ImCreateChannelResult, ImCreateFaceToFaceGroupResult, ImCreateGroupInput, ImCreateGroupResult, ImCreatedChannel, ImCreatedGroup, ImCustomerServiceApi, ImDebugOptions, ImDiagnosticCategory, ImDiagnosticError, ImDiagnosticLayer, ImDiagnosticLevel, ImDiagnosticMemoryBuffer, ImDiagnosticMemoryBufferFilter, ImDiagnosticMemoryBufferOptions, ImDiagnosticMemoryBufferSnapshot, ImDiagnosticMessage, ImDiagnosticRecord, ImDiagnosticSink, ImDiagnosticWriter, ImDirectCallAnswerResult, ImDirectCallFailReason, ImDirectCallHangupInput, ImDirectCallHangupReason, ImDirectCallInviteInput, ImDirectCallNotifyAudioInput, ImDirectCallTargetInput, ImDirectCallsApi, ImDirectReadReceiptSettings, ImDirectoryApi, ImDirectoryFieldMatch, ImDirectoryItem, ImDirectoryKind, ImDirectoryPage, ImDirectorySearchApi, ImDirectorySearchItem, ImDirectorySearchResult, ImDraftsApi, ImEmojiCatalogEntry, ImEndpointProvider, ImEventsApi, ImExpressionAsset, ImExpressionAssetInput, ImExpressionEmojiRecentInput, ImExpressionFavoriteKind, ImExpressionOptions, ImExpressionRecentInput, ImExpressionRecentItem, ImExpressionRecentItemKind, ImExpressionsApi, ImFaceToFaceGroup, ImFailureCatalog, ImFileBody, ImFilesAlbumBody, ImForwardOperationResult, ImFriendshipRequestResult, ImGameBody, ImGameType, ImGifAssetInput, ImGiftBody, ImGiftSessionType, ImGiftStatus, ImGiftType, ImGiphyAsset, ImGiphyPage, ImGiphyPageOptions, ImGroupCallAnswerInput, ImGroupCallBusyInput, ImGroupCallCreateInput, ImGroupCallJoinInput, ImGroupCallMeetingSnapshot, ImGroupCallMember, ImGroupCallMemberStatus, ImGroupCallStatusInput, ImGroupCallTargetInput, ImGroupCallsApi, ImGroupConversationState, ImGroupMemberPresentation, ImGroupMentionApi, ImGroupPinnedMessage, ImGroupProfile, ImGroupsApi, ImI18n, ImImageBody, ImLastMessageCatalog, ImLifecycleSnapshot, ImLiveRoomBody, ImLiveRoomStatus, ImLiveRoomType, ImLocalDataApi, ImLocalDataInfo, ImLocale, ImLogoutOptions, ImMediaAlbumBody, ImMediaAlbumItem, ImMediaBatchSendResult, ImMediaCatalog, ImMediaConfig, ImMediaTask, ImMediaTasksApi, ImMembershipJoinResult, ImMentionCatalog, ImMessageActionResult, ImMessageBodyKind, ImMessageMention, ImMessageReactionAggregate, ImMessageReactions, ImMessageRef, ImMessageSearchApi, ImMessageView, ImMessageViewBody, ImMessagesByIdResult, ImMiniProgramBody, ImMiniProgramShowType, ImOutboxApi, ImOutboxItem, ImPageToken, ImPartialCatalog, ImPinnedMessageActionResult, ImPinnedMessageErrorKind, ImPinnedMessageOperation, ImPinnedMessageSnapshot, ImProductApplicationUpdate, ImProductAuthInvalidReason, ImProductClient, ImProductEvent, ImProductEventError, ImProductEventMap, ImProductMessage, ImProfileAccessDestination, ImPushApi, ImPushSnapshot, ImQuotedMessagePresentation, ImReactionChangeAction, ImReactionChangeResult, ImReadReceiptSettingsApi, ImRedPacketBody, ImRedPacketType, ImRequestError, ImRequestErrorHandler, ImResourceKind, ImResourceUploadInput, ImResourceUploadProgress, ImResourceUploadResult, ImResourceUploader, ImResourceUploaderConfig, ImRobotBody, ImRobotChatMenuItem, ImRobotCommand, ImRobotConversationBindInput, ImRobotDirectoryItem, ImRobotDirectoryPage, ImRobotDirectoryScope, ImRobotMenuReplyInput, ImRobotModule, ImRobotProfile, ImRobotProfileInput, ImRobotsApi, ImSdkErrorCategory, ImSdkErrorShape, ImSearchApi, ImServiceCatalog, ImServiceTextKey, ImSessionApi, ImSessionFavoriteAlbumItem, ImSessionFavoriteFileItem, ImSessionFavoriteItem, ImSessionFavoriteKind, ImSessionFavoritesApi, ImSessionLifecycleState, ImSettingsApi, ImStickerAssetInput, ImStickerBody, ImStickerPack, ImSupportedConversationRef, ImSystemCatalog, ImTextResolver, ImTextSearchMatch, ImTextSearchMatchOptions, ImTextSearchMatcher, ImTextSearchRange, ImThreadActiveDateSnapshot, ImThreadDateMarkerMetric, ImThreadDecoration, ImThreadEncryptionItem, ImThreadIntent, ImThreadItem, ImThreadPresentationAdapter, ImThreadReadActions, ImThreadReadTargetResolver, ImThreadViewportMetrics, ImTimeCatalog, ImTransferBody, ImTransferSessionType, ImTransferStatus, ImVideoBody, ImVoiceBody, ImWebPushSubscription, ImWeekdayKey, ImageMessageOptions, ImagePreviewMetadata, IncomingMessageFollowInput, InitialHistoryViewportFillInput, InitialViewportCompletionInput, LinkSegment, LiveRoomMessageOptions, LocalConversationHistoryClearResult, LocalMessageDeletionResult, LocalVideoPreviewMetadata, MediaAlbumItemInput, MediaAlbumMessageOptions, MediaBatchBudgetOptions, MediaBatchLimitInfo, MediaFileClassification, MediaLimitItem, MediaObjectUrlLease, MediaPresentationFit, MediaPresentationPolicy, MediaPresentationRule, MediaPresentationSourceCandidate, MediaPresentationSourceQuality, MediaSendBatchResult, MediaTransferErrorCode, MediaTransferPresentation, MediaUploadCredentials, MediaUploadCredentialsProvider, MediaUploadCredentialsRequest, MemberTargetCapabilityAction, MemberTargetCapabilityInput, MentionCandidate, MentionCandidatePage, MentionInput, MessageCapabilityAction, MessageCapabilityInput, MessageContentType, MessageLocateScrollProtectionInput, MessageNotificationDecision, MessageNotificationInput, MessageSearchPreviewOptions, MessageSearchPreviewSegment, MessageWindowInfo, MessageWindowPage, MessagesByIdFailure, MigrateImCachePrefixInput, MiniProgramGamePreviewInput, MiniProgramGamePreviewLayout, MiniProgramHostLocale, MiniProgramMessageOptions, MiniProgramOpenUrlInput, NewMessageBadgeController, NewMessageBadgeCountListener, NewMessageBadgeVisibilityInput, NewerHistoryPageTriggerInput, OlderHistoryPrefetchInput, PrependAnchorCandidate, PrependAnchorViewport, PrependMessageAnchorPosition, ProductConversationListType, ProductHandleConversationType, ProductMessageSearchPage, ProductMessageSearchPreviewPart, ProductMessageSearchResult, RemoteMessageBadgeTrackingInput, ResolveMediaPresentationInput, ResolveTextOptions, ResolvedConversationBackground, ResolvedMediaPresentation, RichExtraSegment, RobotConversationCapabilities, RuntimeClientOperation, RuntimeOperation, SearchBatchResult, SearchFilesInput, SearchMessagesInput, SearchTextMessagesInput, SegmentMatch, SegmentMatcher, SendCapabilityMode, SendCommandHooks, SendMessageResult, SendVoicePayload, SenderProfileEntry, ServiceNoteHooks, StandaloneEmojiMessage, StickerAssetKind, TextMessageOptions, TextSegment, TransferMessageOptions, UnicodeEmojiEntry, UnknownMessageBody, UserProfile, VideoMessageOptions, VideoPreviewMetadata, VisibleChannelMiniProgramRels, VoiceCapabilities, VoiceErrorCode, VoiceMessageMetadata, VoicePlayer, VoicePlayerOptions, VoicePlayerState, VoiceRecordingResult, VoiceRecordingSession, VoiceRecordingSessionOptions, VoiceRecordingState, VoiceToggleOptions };
|
|
10989
|
+
export type { ApplySessionResult, BrowseMessagesInput, CanPinMessageInput, CapabilityAvailability, CapabilityDecision, CapabilityReason, CenteredMessageScrollInput, ChannelAccessSnapshot, ChannelBaseSessionState, ChannelConversationCapabilities, ChannelConversationMessageApi, ChannelJoinApplication, ChannelJoinApplicationNotification, ChannelJoinApplicationPage, ChannelMember, ChannelMemberPage, ChannelMentionMember, ChannelMentionMemberPage, ChannelMiniProgramOpenGame, ChannelMiniProgramRel, ChannelMiniProgramRelConfigType, ChannelMiniProgramRelOpenDecision, ChannelMiniProgramRelOpenSurface, ChannelMuteReason, ChannelPermissionSet, ChannelProfile, ChannelRole, ChannelSessionState, ChatMediaMessageRef, ChatProfileAdapter, ChatRuntime, ChatRuntimeCredentials, ChatRuntimeFactories, ChatRuntimeHostDeps, ChatRuntimeOpResult, ContactCardInput, ContactMessageOptions, ConversationBackgroundPreset, ConversationBackgroundSelection, ConversationCapabilityAction, ConversationCapabilitySnapshot, ConversationDraft, ConversationDraftApi, ConversationEntryUnreadNavigation, ConversationEntryUnreadSnapshot, ConversationHandle, ConversationHandleSnapshot, ConversationInitialPosition, ConversationLastMessageSummary, ConversationListItem, ConversationListMention, ConversationListPresentation, ConversationListPresentationLabels, ConversationListPresentationOptions, ConversationListPreviewMediaKind, ConversationListPreviewSegment, ConversationMessageApi, ConversationOpenOptions, ConversationPrefetchController, ConversationPrefetchControllerOptions, ConversationPrefetchOptions, ConversationPrefetchResult, ConversationRef, ConversationSearchCategory, ConversationSearchPage, ConversationSearchResult, ConversationSystemSummary, ConversationType, CreateThreadItemsInput, CustomerServiceConversationCapabilities, DelayedLoadingIndicator, DelayedLoadingIndicatorOptions, DirectConversationCapabilities, DirectConversationMessageApi, DraftInput, EditTextOptions, EmojiEntry, EmojiRecentItem, EmojiSegment, ExpressionMessageOptions, FileMessageOptions, FormatFailureContext, FormatLastMessageContext, FormatMediaPlaceholderContext, FormatServiceTextContext, FormatSystemMessageContext, FormatTimeDisplayContext, ForwardCommandHooks, ForwardFailReason, ForwardItemStatus, ForwardMessageFailure, ForwardMessagesInput, ForwardMessagesResult, ForwardTarget, ForwardedMessageRef, GameMessageOptions, GifFileClassification, GifMessageOptions, GiftMessageOptions, GroupConversationCapabilities, GroupConversationMessageApi, GroupMemberItem, GroupProfile, HighlightSegment, ImAppearanceSettingsApi, ImApplicationItem, ImApplicationRef, ImApplicationsApi, ImAuthIssue, ImAuthProvider, ImBlockedContact, ImCacheOptions, ImCachePrefixMigrationContext, ImCachePrefixMigrator, ImCallKind, ImCallOutcome, ImCallRecordBody, ImCatalog, ImCatalogOverrides, ImChannelConversationAccessSnapshot, ImChannelMemberPresentation, ImChannelMentionApi, ImChannelMentionPresentation, ImChannelMiniProgramRel, ImChannelPermissions, ImChannelPinnedMessage, ImChannelProfile, ImChannelProfilePresentation, ImChannelRole, ImChannelState, ImChannelsApi, ImChatFontScale, ImClientActivityApi, ImClientActivitySnapshot, ImClientOptions, ImConnectionState, ImContactBody, ImContactKind, ImContactProfile, ImContactRelationship, ImContactRemarkPhone, ImContactSearchResult, ImContactsApi, ImConversationBackgroundApi, ImConversationCapabilitiesApi, ImConversationListApi, ImConversationListSnapshot, ImConversationListState, ImConversationSearchApi, ImCoreApiOptions, ImCreateChannelInput, ImCreateChannelResult, ImCreateFaceToFaceGroupResult, ImCreateGroupInput, ImCreateGroupResult, ImCreatedChannel, ImCreatedGroup, ImCustomerServiceApi, ImDebugOptions, ImDiagnosticCategory, ImDiagnosticError, ImDiagnosticLayer, ImDiagnosticLevel, ImDiagnosticMemoryBuffer, ImDiagnosticMemoryBufferFilter, ImDiagnosticMemoryBufferOptions, ImDiagnosticMemoryBufferSnapshot, ImDiagnosticMessage, ImDiagnosticRecord, ImDiagnosticSink, ImDiagnosticWriter, ImDirectCallAnswerResult, ImDirectCallFailReason, ImDirectCallHangupInput, ImDirectCallHangupReason, ImDirectCallInviteInput, ImDirectCallNotifyAudioInput, ImDirectCallTargetInput, ImDirectCallsApi, ImDirectReadReceiptSettings, ImDirectoryApi, ImDirectoryFieldMatch, ImDirectoryItem, ImDirectoryKind, ImDirectoryPage, ImDirectorySearchApi, ImDirectorySearchItem, ImDirectorySearchResult, ImDraftsApi, ImEmojiCatalogEntry, ImEndpointProvider, ImEventsApi, ImExpressionAsset, ImExpressionAssetInput, ImExpressionEmojiRecentInput, ImExpressionFavoriteKind, ImExpressionOptions, ImExpressionRecentInput, ImExpressionRecentItem, ImExpressionRecentItemKind, ImExpressionsApi, ImFaceToFaceGroup, ImFailureCatalog, ImFileBody, ImFilesAlbumBody, ImForwardOperationResult, ImFriendshipRequestResult, ImGameBody, ImGameType, ImGifAssetInput, ImGiftBody, ImGiftSessionType, ImGiftStatus, ImGiftType, ImGiphyAsset, ImGiphyPage, ImGiphyPageOptions, ImGroupCallAnswerInput, ImGroupCallBusyInput, ImGroupCallCreateInput, ImGroupCallJoinInput, ImGroupCallMeetingSnapshot, ImGroupCallMember, ImGroupCallMemberStatus, ImGroupCallStatusInput, ImGroupCallTargetInput, ImGroupCallsApi, ImGroupConversationState, ImGroupMemberPresentation, ImGroupMentionApi, ImGroupPinnedMessage, ImGroupProfile, ImGroupsApi, ImI18n, ImImageBody, ImLastMessageCatalog, ImLifecycleSnapshot, ImLiveRoomBody, ImLiveRoomStatus, ImLiveRoomType, ImLocalDataApi, ImLocalDataInfo, ImLocale, ImLogoutOptions, ImMediaAlbumBody, ImMediaAlbumItem, ImMediaBatchSendResult, ImMediaCatalog, ImMediaConfig, ImMediaTask, ImMediaTasksApi, ImMembershipJoinResult, ImMentionCatalog, ImMessageActionResult, ImMessageBodyKind, ImMessageMention, ImMessageReactionAggregate, ImMessageReactions, ImMessageRef, ImMessageSearchApi, ImMessageView, ImMessageViewBody, ImMessagesByIdResult, ImMiniProgramBody, ImMiniProgramShowType, ImOutboxApi, ImOutboxItem, ImPageToken, ImPartialCatalog, ImPinnedMessageActionResult, ImPinnedMessageErrorKind, ImPinnedMessageOperation, ImPinnedMessageSnapshot, ImProductApplicationUpdate, ImProductAuthInvalidReason, ImProductClient, ImProductEvent, ImProductEventError, ImProductEventMap, ImProductMessage, ImProfileAccessDestination, ImPushApi, ImPushSnapshot, ImQuotedMessagePresentation, ImReactionChangeAction, ImReactionChangeResult, ImReadReceiptSettingsApi, ImRedPacketBody, ImRedPacketType, ImRequestError, ImRequestErrorHandler, ImResourceKind, ImResourceUploadInput, ImResourceUploadProgress, ImResourceUploadResult, ImResourceUploader, ImResourceUploaderConfig, ImRobotBody, ImRobotChatMenuItem, ImRobotCommand, ImRobotConversationBindInput, ImRobotDirectoryItem, ImRobotDirectoryPage, ImRobotDirectoryScope, ImRobotMenuReplyInput, ImRobotModule, ImRobotProfile, ImRobotProfileInput, ImRobotsApi, ImSdkErrorCategory, ImSdkErrorShape, ImSearchApi, ImServiceCatalog, ImServiceTextKey, ImSessionApi, ImSessionFavoriteAlbumItem, ImSessionFavoriteFileItem, ImSessionFavoriteItem, ImSessionFavoriteKind, ImSessionFavoritesApi, ImSessionLifecycleState, ImSettingsApi, ImStickerAssetInput, ImStickerBody, ImStickerPack, ImSupportedConversationRef, ImSystemCatalog, ImTextResolver, ImTextSearchMatch, ImTextSearchMatchOptions, ImTextSearchMatcher, ImTextSearchRange, ImThreadActiveDateSnapshot, ImThreadDateMarkerMetric, ImThreadDecoration, ImThreadEncryptionItem, ImThreadIntent, ImThreadItem, ImThreadPresentationAdapter, ImThreadReadActions, ImThreadReadTargetResolver, ImThreadViewportMetrics, ImTimeCatalog, ImTransferBody, ImTransferSessionType, ImTransferStatus, ImVideoBody, ImVoiceBody, ImWebPushSubscription, ImWeekdayKey, ImageMessageOptions, ImagePreviewMetadata, IncomingMessageFollowInput, InitialHistoryViewportFillInput, InitialViewportCompletionInput, LinkSegment, LiveRoomMessageOptions, LocalConversationHistoryClearResult, LocalMessageDeletionResult, LocalVideoPreviewMetadata, MediaAlbumItemInput, MediaAlbumMessageOptions, MediaBatchBudgetOptions, MediaBatchLimitInfo, MediaFileClassification, MediaLimitItem, MediaObjectUrlLease, MediaPresentationFit, MediaPresentationPolicy, MediaPresentationRule, MediaPresentationSourceCandidate, MediaPresentationSourceQuality, MediaSendBatchResult, MediaTransferErrorCode, MediaTransferPresentation, MediaUploadCredentials, MediaUploadCredentialsProvider, MediaUploadCredentialsRequest, MemberTargetCapabilityAction, MemberTargetCapabilityInput, MentionCandidate, MentionCandidatePage, MentionInput, MessageCapabilityAction, MessageCapabilityInput, MessageContentType, MessageLocateScrollProtectionInput, MessageNotificationDecision, MessageNotificationInput, MessageSearchPreviewOptions, MessageSearchPreviewSegment, MessageWindowInfo, MessageWindowPage, MessagesByIdFailure, MigrateImCachePrefixInput, MiniProgramGamePreviewInput, MiniProgramGamePreviewLayout, MiniProgramHostLocale, MiniProgramMessageOptions, MiniProgramOpenUrlInput, NewMessageBadgeController, NewMessageBadgeCountListener, NewMessageBadgeVisibilityInput, NewerHistoryPageTriggerInput, OlderHistoryPrefetchInput, PrependAnchorCandidate, PrependAnchorViewport, PrependMessageAnchorPosition, ProductConversationListType, ProductHandleConversationType, ProductMessageSearchPage, ProductMessageSearchPreviewPart, ProductMessageSearchResult, RemoteMessageBadgeTrackingInput, ResolveMediaPresentationInput, ResolveTextOptions, ResolvedConversationBackground, ResolvedMediaPresentation, RichExtraSegment, RobotConversationCapabilities, RuntimeClientOperation, RuntimeOperation, SearchBatchResult, SearchFilesInput, SearchMessagesInput, SearchTextMessagesInput, SegmentMatch, SegmentMatcher, SendCapabilityMode, SendCommandHooks, SendMessageResult, SendVoicePayload, SenderProfileEntry, ServiceNoteHooks, StandaloneEmojiMessage, StickerAssetKind, TextMessageOptions, TextSegment, TransferMessageOptions, UnicodeEmojiEntry, UnknownMessageBody, UserProfile, VideoMessageOptions, VideoPreviewMetadata, VisibleChannelMiniProgramRels, VoiceCapabilities, VoiceErrorCode, VoiceMessageMetadata, VoicePlayer, VoicePlayerOptions, VoicePlayerState, VoiceRecordingResult, VoiceRecordingSession, VoiceRecordingSessionOptions, VoiceRecordingState, VoiceToggleOptions };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createRequestTracker as e}from"../request-tracker.js";import{CmdId as i,ErrCode as t}from"../../../im-protocol/src/protobuf/gen/im.pub_pb.js";import{cmClientStateAckCodec as r,cmClientStateCodec as s}from"../../../im-protocol/src/protobuf/registry.js";import{encodeFrame as n}from"../../../im-protocol/src/frame-codec.js";function o(o){let d=!1,c=!1,u=0n;const l=e();let a,v,f={status:"idle"};const m=/* @__PURE__ */new Set;function b(e){try{e({...f})}catch{o.onListenerError()}}function S(e){f=e;for(const e of[...m])b(e)}function g(){v&&clearTimeout(v.timer),v=void 0}function y(e,i){const t=v;g(),S({status:"error",visibility:a?.visibility,sequence:t?.sequence.toString(),error:e,...void 0===i?{}:{serverCode:i}})}function I(){c||(a=void 0,g(),S({status:"idle"}))}function p(){if(c||!a)return;if(a.userId!==o.getSelfId())return void I();if(g(),!d)return void S({status:"pending",visibility:a.visibility});u+=1n;const e=a,t=l.nextSeq(),r=n({command:i.CM_CLIENT_STATE,msgSeq:t,body:s.encode(s.create({sUserId:BigInt(e.userId),nState:"visible"===e.visibility?1:2,nSeq:u,nClientTime:BigInt(Date.now())}))}),f={...e,sequence:u,msgSeq:t,timer:setTimeout(()=>{v===f&&y("timeout")},o.timeoutMs??8e3)};if(v=f,S({status:"syncing",visibility:e.visibility,sequence:u.toString()}),v===f&&d&&!c&&a===e)if(e.userId===o.getSelfId())try{o.sendFrame(r)}catch{v===f&&y("send-failed")}else I()}return{api:{setVisibility(e){if(c)throw new Error("页面状态上报已销毁");if(!/^[1-9]\d*$/.test(e.userId)||e.userId!==o.getSelfId()||BigInt(e.userId)>9223372036854775807n)throw new Error("页面状态账号与当前会话不一致或格式无效");if("visible"!==e.visibility&&"hidden"!==e.visibility)throw new Error("页面状态必须为 visible 或 hidden");a={...e},p()},clear:I,snapshot:()=>({...f}),subscribe:e=>(c||m.add(e),b(e),()=>{m.delete(e)})},commandHandlers:[{command:i.CM_CLIENT_STATE_ACK,handler(e,i,s){if(!v||c||!d||s?.msgSeq!==v.msgSeq)return;if(v.userId!==o.getSelfId())return void I();let n;try{n=r.decode(i)}catch{return void y("invalid-ack")}if(String(n.sUserId)!==v.userId)return void y("invalid-ack");if(n.nErr!==t.NON_ERR)return void y("server-rejected",n.nErr);if(n.nSeq!==v.sequence||n.nState!==("visible"===v.visibility?1:2)||0===n.nForegroundTtl||0n===n.nServerTime)return void y("invalid-ack");const u=v;g(),S({status:"synced",visibility:u.visibility,sequence:u.sequence.toString(),foregroundTtlSeconds:n.nForegroundTtl,serverTimeMs:n.nServerTime.toString()})}}],setAuthenticated(e){c||d===e||(d=e,u=0n,g(),a?p():S({status:"idle"}))},onHeartbeat(){d&&"visible"===a?.visibility&&p()},dispose(){c||(c=!0,a=void 0,g(),S({status:"disposed"}),m.clear())}}}export{o as createClientActivity};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLoginHandler as e}from"../login/login-handler.js";import{sendExpressionMessage as t}from"../message-flow/expression/expression-message.js";import{sendGameMessage as n}from"../message-flow/game/game-message.js";import{sendGiftMessage as o}from"../message-flow/gift/gift-message.js";import{sendLiveRoomMessage as r}from"../message-flow/live-room/live-room-message.js";import{sendMiniProgramMessage as i}from"../message-flow/mini-program/mini-program-message.js";import{sendTransferMessage as a}from"../message-flow/transfer/transfer-message.js";import{createPacketRouter as s}from"../packet-router.js";import{computeBackoffDelay as d}from"./backoff.js";import{createHeartbeatManager as c}from"./heartbeat-manager.js";import{createDefaultSendStrategyRegistry as l}from"../message-flow/send/send-strategy-registry.js";import{createOutboxManager as m}from"../outbox/outbox-manager.js";import{createReadReporter as u}from"../read/read-reporter.js";import{createRecallManager as f}from"../message-flow/recall/recall-manager.js";import{createChannelMessageDeletionManager as g}from"../message-flow/recall/channel-message-deletion-manager.js";import{createRecallReceiveHandlers as p}from"../message-flow/recall/recall-receive-handlers.js";import{createEditManager as v}from"../message-flow/edit/edit-manager.js";import{createEditReceiveHandlers as h}from"../message-flow/edit/edit-receive-handlers.js";import{createMediaSender as w}from"../message-flow/media/media-sender.js";import{createDirectReadSyncCoordinator as y}from"../message-flow/read/direct-read-sync.js";import{encodeFrame as S,decodeFrameStream as I}from"../../../im-protocol/src/frame-codec.js";import{CmdId as M,ErrCode as A}from"../../../im-protocol/src/protobuf/gen/im.pub_pb.js";import{cmKickoutNotificationCodec as C}from"../../../im-protocol/src/protobuf/registry.js";import{forwardMessages as b}from"../message-flow/forward/forward-messages.js";function E(E,T={}){const{transport:k,authProvider:x,endpointProvider:P,emitter:R}=E,U=T.heartbeatIntervalMs??1e4,j=T.heartbeatMaxMissed??3,F=T.foregroundProbeTimeoutMs??5e3,O=T.loginTimeoutMs??T.readTimeoutMs??3e4,D={baseDelayMs:T.reconnect?.baseDelayMs??1e3,maxDelayMs:T.reconnect?.maxDelayMs??3e4,jitter:T.reconnect?.jitter??!0};let _,L="idle",V=!0,K=0,G=!1,$=new Uint8Array(0),B=!1,N=0,H="";function q(e){L!==e&&(E.logger?.("connection:state-transition",{from:L,to:e,selfId:H}),L=e,R.emit({type:"connection:changed",state:e}))}function Y(e){R.emit({type:"error",error:e})}function z(e,t){const n=N;e?.catch(e=>{n===N&&Y({scope:"unknown",message:t,cause:e})})}function W(e){var t;k.send((t=e,t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength))).catch(e=>{Y({scope:"transport",message:"发送失败",cause:e})})}const J=c({sendPing:()=>W(S({command:M.SYSTEM_HEARTBEAT})),onUnhealthy:()=>{E.logger?.("connection:heartbeat-unhealthy",{stateBefore:L,selfId:H}),Y({scope:"transport",message:"心跳连续未 ACK,链路判定不健康"}),pe()}},{intervalMs:U,maxMissed:j,probeTimeoutMs:F}),Q=e({authProvider:x,sendFrame:W,logger:E.logger},{timeoutMs:O}),X=E.sendStrategies??l(),Z=E.domainState?m({domainState:E.domainState,sendFrame:W,getSelfId:()=>H,isAuthenticated:()=>"authenticated"===L,sendStrategies:X,crypto:E.encryptSend?.crypto,resolvePublicKey:E.encryptSend?.resolvePublicKey,storage:E.storage,onStorageError:(e,t)=>Y({scope:"storage",message:e,cause:t}),onUpdated:e=>E.emitter.emit({type:"outbox:updated",conversation:e.conversation,item:e})},{ackTimeoutMs:T.readTimeoutMs??3e4}):void 0,ee=E.domainState?u({domainState:E.domainState,sendFrame:W,getSelfId:()=>H,isAuthenticated:()=>"authenticated"===L,emitter:R,logger:E.logger,canSendReadReceipt:E.canSendDirectReadReceipt},{readAckTimeoutMs:T.readTimeoutMs??3e4}):void 0,te=E.domainState?y({domainState:E.domainState,sendFrame:W,getSelfId:()=>H,isAuthenticated:()=>"authenticated"===L,emitter:R,logger:E.logger}):void 0,ne=E.domainState?f({domainState:E.domainState,sendFrame:W,getSelfId:()=>H,isAuthenticated:()=>"authenticated"===L,strategies:E.recallStrategies}):void 0,oe=void 0!==E.domainState&&void 0!==E.channelMessageDeletion?g({domainState:E.domainState,sendFrame:W,getSelfId:()=>H,isAuthenticated:()=>"authenticated"===L,resolveProfile:E.channelMessageDeletion.resolveProfile,onPermissionDenied:E.channelMessageDeletion.onPermissionDenied}):void 0,re=void 0!==E.domainState&&void 0!==ne?p({domainState:E.domainState,sendFrame:W,getSelfId:()=>H,onRecallAck:ne.onRecallAck,onChannelMessageDeletionAck:e=>oe?.onDeleteAck(e),logger:E.logger}):[],ie=E.domainState?v({getSelfId:()=>H,sendFrame:W,isAuthenticated:()=>"authenticated"===L,domainState:E.domainState,crypto:E.encryptSend?.crypto,resolvePublicKey:E.encryptSend?.resolvePublicKey,resolveGroupKey:E.encryptSend?.resolveGroupKey,strategies:E.editStrategies}):void 0,ae=void 0!==E.domainState&&void 0!==ie?h({onEditAck:ie.onEditAck}):[],se=void 0!==E.domainState&&void 0!==Z&&void 0!==E.media?w({getSelfId:()=>H,domainState:E.domainState,outbox:Z,mediaTransfer:E.media.transfer,mediaPreview:E.media.preview,mediaAssetCache:E.media.assetCache,onMediaAssetCacheError:E.media.onAssetCacheError,onMediaTransferError:E.media.onTransferError,onMediaAlbumContentSize:E.media.onAlbumContentSize,emitter:R,crypto:E.encryptSend?.crypto,maxConcurrentUploads:E.media.maxConcurrentUploads,recoveryPort:E.media.recoveryPort,retainFailedUploads:E.media.retainFailedUploads,shouldPersistUpload:E.media.shouldPersistUpload,waitUntilOnline:E.media.waitUntilOnline,isOnline:E.isOnline}):void 0;function de(e,t){return void 0===se?Promise.reject(new Error(`${e} 不可用:createImConnection 未注入 domainState 或 media 端口`)):""===H?Promise.reject(new Error(`${e} 需先成功登录一次以获取本端 id(尚未鉴权过)`)):t(se)}function ce(e,t,n,o){const r=E.domainState?.getConversationMessage({conversationId:n.conversationId,conversationType:n.conversationType},t);if(void 0===r||r.conversationId!==n.conversationId||r.conversationType!==n.conversationType||r.contentType!==o&&("file"!==o||"filesAlbum"!==r.contentType||1!==r.body.filesAlbum?.items.length)||"failed"!==r.status||void 0!==r.recalled||void 0!==r.deletedForEveryone||r.senderId!==H||"media.uploadInterrupted"!==r.failure?.displayCode&&"media.cancelled"!==r.failure?.displayCode&&("media.uploadTimeout"!==r.failure?.displayCode||!1!==r.failure.retryable))throw new Error(`${e} 只允许替换当前精确会话中源文件已释放的${"video"===o?"视频":"文件"}消息`);return r}const le=E.domainState&&Z?s({isActive:()=>V&&"authenticated"===L,domainState:E.domainState,outbox:Z,onReadAck:ee?.onReadAck,onSyncReadAck:te?.onAck,onSyncReadDeliver:te?.onDeliver,sendFrame:W,getSelfId:()=>H,emitter:R,logger:E.logger,decrypt:E.decrypt,commandHandlers:[...E.commandHandlers??[],...re,...ae]}):void 0;function me(){"open"!==k.state&&"connecting"!==k.state&&"closing"!==k.state||k.close().catch(()=>{})}function ue(){void 0!==_&&(clearTimeout(_),_=void 0)}async function fe(){try{return null!==(e=await x.getLoginContext())&&""!==e.userId.trim()&&""!==e.token.trim()?"available":"missing"}catch(e){return Y({scope:"login",message:"检查登录上下文失败",cause:e}),"unavailable"}var e}function ge(e,t){Y({scope:"transport",message:e,cause:t}),J.stop(),q("disconnected")}function pe(){if("reconnecting"===L||"suspended"===L)return;const e=++N;J.stop(),Q.cancel(),Z?.reset(),ee?.reset(),ne?.reset(),oe?.reset(),ie?.reset(),q("reconnecting"),me(),fe().then(t=>{"reconnecting"===L&&e===N&&("missing"!==t?function(){if(void 0!==_)return;const e=d(K,D);K+=1,_=setTimeout(()=>{_=void 0,Se()},e)}():we({code:0,reason:"token_expired"}))})}function ve(e="offline"){const t="idle"===L||"disconnected"===L||"disconnecting"===L;"offline"!==e||!t&&"suspended"!==L?(ue(),N+=1,"offline"===e&&z(se?.pauseAll(),"页面离开时暂停上传失败"),J.stop(),Q.cancel(),"session-ended"===e&&se?.cancelAll("session-ended"),Z?.reset({discardInFlight:"session-ended"===e}),ee?.reset(),ne?.reset(),oe?.reset(),ie?.reset(),t||q("suspended"),me()):z(se?.pauseAll(),"页面离开时暂停上传失败")}function he(){"suspended"===L&&V&&(!1!==E.isOnline?.()?(K=0,Se()):q("offline"))}function we(e){"idle"!==L&&"disconnected"!==L&&(E.logger?.("connection:auth-invalid-terminal",{reason:e.reason,code:`0x${e.code.toString(16)}`,stateBefore:L,selfId:H}),ue(),N+=1,J.stop(),Q.cancel(),q("disconnected"),me(),se?.cancelAll("session-ended"),Z?.reset({discardInFlight:!0}),ee?.reset(),ne?.reset(),oe?.reset(),ie?.reset(),R.emit({type:"auth:invalid",issue:e}),Promise.resolve().then(()=>x.onAuthInvalid?.(e)).catch(e=>Y({scope:"login",message:"onAuthInvalid 回调异常",cause:e})))}async function ye(){const e=await Q.login();"canceled"!==e.type&&"authenticating"===L&&function(e){switch(e.type){case"success":K=0,B=!1,e.selfId&&(H=e.selfId),q("authenticated"),J.start(),Z?.onAuthenticated(),z(se?.resumePaused(),"网络恢复后继续上传失败"),ee?.onAuthenticated(),te?.onAuthenticated(),E.readStrategies?.onAuthenticated(),E.onAuthenticated?.();break;case"auth-invalid":if("token_expired"===e.issue.reason&&0!==e.issue.code&&!B)return B=!0,Y({scope:"login",message:"token 失效,自动重试登录一次"}),void pe();we(e.issue);break;case"retry":Y(e.error),pe()}}(e)}async function Se(){if(!V)return ue(),void q("suspended");if(!1===E.isOnline?.())return ue(),J.stop(),z(se?.pauseAll("offline"),"离线探针暂停上传失败"),void q("offline");const e=++N;q("connecting"),G=!1,$=new Uint8Array(0);const t=await fe();if(e!==N)return;if("missing"===t)return void we({code:0,reason:"token_expired"});if("unavailable"===t)return void pe();let n;try{n=await P.getEndpoints()}catch(t){if(e!==N)return;return void ge("获取连接端点失败",t)}if(e!==N)return;const o=n[0];if(void 0!==o)if(function(e){try{const t=new URL(e);return"ws:"===t.protocol||"wss:"===t.protocol}catch{return!1}}(o.url)){try{await k.connect([o])}catch(t){if(e!==N)return;return Y({scope:"transport",message:"连接失败",cause:t}),void pe()}e!==N&&me()}else ge(`连接端点 URL 非法:${o.url}`);else ge("无可用连接端点(getEndpoints 返回空数组)")}function Ie(e,t,n){switch(e){case M.CM_LOGIN_ACK:Q.onLoginAck(t);break;case M.SYSTEM_HEARTBEAT_ACK:J.onAck();break;case M.CM_KICKOUT_NOTIFICATION:if(void 0!==E.logger)try{const e=C.decode(t);E.logger("connection:kickout-received",{kickedUserId:String(e.sUserId),selfId:H,matchesSelf:String(e.sUserId)===H,entryIp:e.ip,entryPort:e.port,stateBefore:L})}catch(e){E.logger("connection:kickout-decode-failed",{message:e?.message,stateBefore:L})}we({code:A.ERR_CM_AUTH_KICKEDOUT,reason:"kicked"});break;default:le?.route(e,t,{msgSeq:n})}}function Me(){return"authenticating"===L||"authenticated"===L}function Ae(e){if(!Me())return;const t=N;let n;$=function(e,t){if(0===e.length)return t;const n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}($,new Uint8Array(e));try{const e=I($);n=e.frames,$=e.remainder}catch(e){return Y({scope:"protocol",message:"帧解析失败,连接重置",cause:e}),void pe()}for(const e of n){if(!Me()||t!==N)return;Ie(e.header.command,e.body,e.header.msgSeq)}}return k.on("open",()=>{"connecting"===L&&(q("authenticating"),ye())}),k.on("message",({data:e})=>Ae(e)),k.on("error",({error:e})=>{Y({scope:"transport",message:"transport 错误",cause:e})}),k.on("close",({code:e,reason:t,wasClean:n})=>{if(J.stop(),E.logger?.("connection:transport-closed",{code:e,reason:t,wasClean:n,stateBefore:L,intentionalClose:G,nextPath:G||"disconnecting"===L?"disconnected":"idle"===L||"disconnected"===L||"reconnecting"===L||"suspended"===L||"offline"===L?"ignored":"reconnect"}),G||"disconnecting"===L)return G=!1,void q("disconnected");"idle"!==L&&"disconnected"!==L&&"reconnecting"!==L&&"suspended"!==L&&"offline"!==L&&pe()}),{get state(){return L},setConnectionAllowed(e){V!==e&&(V=e,e||ve("session-ended"))},async connect(){"connecting"!==L&&"authenticating"!==L&&"authenticated"!==L&&(ue(),K=0,await Se())},disconnect(){ue(),N+=1,J.stop(),Q.cancel(),Z?.reset(),ee?.reset(),ne?.reset(),oe?.reset(),ie?.reset(),G=!0,"idle"!==L&&"disconnected"!==L?(q("disconnecting"),"open"!==k.state&&"connecting"!==k.state&&"closing"!==k.state||k.close().catch(()=>{}),"closed"!==k.state&&"idle"!==k.state||q("disconnected")):q("disconnected")},notifyOnline(){if("offline"===L)return K=0,void Se();"reconnecting"===L&&(ue(),Se())},notifyOffline(){z(se?.pauseAll("offline"),"网络离线时暂停上传失败"),"idle"!==L&&"disconnected"!==L&&"disconnecting"!==L&&"suspended"!==L&&"offline"!==L&&(ue(),N+=1,J.stop(),Q.cancel(),Z?.reset(),ee?.reset(),ne?.reset(),oe?.reset(),ie?.reset(),q("offline"),me())},notifyVisible(){if("suspended"!==L){if("offline"===L&&!0===E.isOnline?.())return K=0,void Se();if("reconnecting"===L)return ue(),void Se();if("authenticated"===L){const e=N;fe().then(t=>{"authenticated"===L&&e===N&&("missing"!==t?J.probe():we({code:0,reason:"token_expired"}))})}}else he()},suspendForPageLifecycle:ve,resumeFromPageLifecycle:he,suppressDirectReadReceipts(e){ee?.suppress(e)},resumeDirectReadReceipts(e){ee?.resume(e)},reportDirectMediaConsumed(e,t){ee?.reportConsumedMedia(e,t),te?.reportConsumedMedia?.(e,t)},sendText(e){if(void 0===Z)throw new Error("sendText 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===H)throw new Error("sendText 需先成功登录一次以获取本端 id(尚未鉴权过)");return Z.enqueueText(e)},sendContact(e){if(void 0===Z)throw new Error("sendContact 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===H)throw new Error("sendContact 需先成功登录一次以获取本端 id(尚未鉴权过)");return Z.enqueueContact(e)},forwardMessages(e){if(void 0===Z)throw new Error("forwardMessages 不可用:createImConnection 未注入 domainState(仅连接模式)");const t=E.domainState;if(void 0===t)throw new Error("forwardMessages 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===H)throw new Error("forwardMessages 需先成功登录一次以获取本端 id(尚未鉴权过)");return b({outbox:Z,sendStrategies:X,resolveCurrentMessage:e=>t.getConversationMessage(e,e.id)},e)},recallMessage:e=>void 0===ne?Promise.reject(new Error("recallMessage 不可用:createImConnection 未注入 domainState(仅连接模式)")):ne.recall(e),deleteChannelMessageForEveryone:e=>void 0===oe?Promise.reject(new Error("deleteChannelMessageForEveryone 不可用:未装配 CHANNEL 管理员删除依赖")):oe.deleteForEveryone(e),editMessage:e=>void 0===ie?Promise.reject(new Error("editMessage 不可用:createImConnection 未注入 domainState(仅连接模式)")):ie.edit(e),sendImage:e=>de("sendImage",t=>t.sendImage(e)),sendVideo:e=>de("sendVideo",t=>t.sendVideo(e)),sendVoice:e=>de("sendVoice",t=>t.sendVoice(e)),sendFile:e=>de("sendFile",t=>t.sendFile(e)),sendGif:e=>de("sendGif",t=>t.sendGif(e)),sendMediaAlbum:e=>de("sendMediaAlbum",t=>t.sendMediaAlbum(e)),sendExpression(e){if(void 0===Z)throw new Error("sendExpression 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===H)throw new Error("sendExpression 需先成功登录一次以获取本端 id(尚未鉴权过)");return t({outbox:Z},e)},sendGame(e){if(void 0===Z)throw new Error("sendGame 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===H)throw new Error("sendGame 需先成功登录一次以获取本端 id(尚未鉴权过)");return n({outbox:Z,randomUint32:E.randomUint32},e)},sendMiniProgram(e){if(void 0===Z)throw new Error("sendMiniProgram 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===H)throw new Error("sendMiniProgram 需先成功登录一次以获取本端 id(尚未鉴权过)");return i({outbox:Z},e)},sendTransfer(e){if(void 0===Z)throw new Error("sendTransfer 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===H)throw new Error("sendTransfer 需先成功登录一次以获取本端 id(尚未鉴权过)");return a({outbox:Z},e)},sendGift(e){if(void 0===Z)throw new Error("sendGift 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===H)throw new Error("sendGift 需先成功登录一次以获取本端 id(尚未鉴权过)");return o({outbox:Z},e)},sendLiveRoom(e){if(void 0===Z)throw new Error("sendLiveRoom 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===H)throw new Error("sendLiveRoom 需先成功登录一次以获取本端 id(尚未鉴权过)");return r({outbox:Z},e)},replaceInterruptedVideo:(e,t)=>de("replaceInterruptedVideo",n=>{const o=ce("replaceInterruptedVideo",e,t,"video");return n.replaceVideo(e,o.createdAt,{...t,...void 0===t.caption&&void 0!==o.body.video?.describe?{caption:o.body.video.describe}:{},...void 0===t.refMessageId&&void 0!==o.refMessageId?{refMessageId:o.refMessageId}:{}})}),replaceInterruptedFile:(e,t)=>de("replaceInterruptedFile",n=>{const o=ce("replaceInterruptedFile",e,t,"file");return n.replaceFile(e,o.createdAt,{...t,..."filesAlbum"===o.contentType?{filesAlbum:!0,caption:o.body.filesAlbum?.caption}:{},...void 0===t.refMessageId&&void 0!==o.refMessageId?{refMessageId:o.refMessageId}:{}})}),cancelMedia(e){se?.cancel(e)},cancelMediaUpload:(e,t)=>se?.cancel(e,t)??!1,pauseMediaUpload:e=>se?.pause(e)??Promise.resolve(!1),resumeMediaUpload:e=>se?.resume(e)??!1,resumePausedMediaUploads:(e,t)=>se?.resumePaused(e,t)??Promise.resolve(),retryMediaUpload:(e,t)=>se?.retry(e,t)??!1,expireRetainedUploads(){se?.expireRetainedUploads()},invalidateMediaAssetCacheWrites(){se?.invalidateAssetCacheWrites()},async disposeMediaTasks(e){await(se?.dispose(e))},recoverMediaUpload:(e,t,n)=>void 0===se?Promise.reject(new Error("IM_MEDIA_RECOVERY_UNAVAILABLE")):de("recoverMediaUpload",o=>o.recoverUpload(e,t,n)),retryMessage(e){!0!==se?.retry(e)&&Z?.retry(e)},retryOutboxMessage:e=>Z?.retry(e)??{accepted:!1,reason:"not-found"},cancelOutboxMessage:e=>Z?.cancel(e)??{accepted:!1,reason:"not-found"},markOutboxConversationTerminated(e,t){Z?.markConversationTerminated(e,t)},clearOutboxConversationTerminated(e){Z?.clearConversationTerminated(e)},terminateConversationSending(e,t){se?.cancelConversation(e),Z?.markConversationTerminated(e,t)},settleConversationRead(e,t){if(void 0===E.domainState)throw new Error("会话已读不可用:未注入 domainState");if("direct"===e.conversationType)return E.domainState.advanceRead(e,t),void te?.report(e.conversationId);const n=E.readStrategies?.resolve(e.conversationType);if(void 0===n)throw new Error(`会话已读未支持类型:${e.conversationType}`);const o={conversationId:e.conversationId,readCursor:t};if("channel"===e.conversationType){if(void 0===n.settleConversationRead)throw new Error("CHANNEL 整会话已读尚未装配");return n.settleConversationRead(o)}return n.markRead(o)},reportVisibleMessages(e,t){if("group"!==e.conversationType&&"channel"!==e.conversationType){if("direct"!==e.conversationType)throw new Error(`可见消息回执未支持类型:${e.conversationType}`);if(void 0===ee)throw new Error("可见消息回执不可用:未注入 domainState");ee.reportVisible(e.conversationId,t)}},markRead(e,t,n){if(void 0===E.domainState)throw new Error("markRead 不可用:createImConnection 未注入 domainState(仅连接模式)");const o=n??E.domainState.getSession(e)?.type;if(void 0===o)throw new Error(`markRead 无法确定会话类型(conversationId=${e}),禁止默认 direct`);if("direct"===o){if(void 0===ee)throw new Error("markRead 不可用:createImConnection 未注入 domainState(仅连接模式)");return E.domainState.advanceRead(e,t),ee.report(e),void te?.report(e)}const r=E.readStrategies?.resolve(o);if(void 0===r)throw new Error(`markRead 暂不支持会话类型「${o}」:未注册对应已读策略,禁止 fallthrough direct`);return r.markRead({conversationId:e,readCursor:t})},sendFrame(e){W(e)},onChatAck(e){Z?.onChatAck(e)},getPendingOutbox:()=>Z?.getPending()??[],async hydrateOutbox(e){await(Z?.hydrate(e))},markOutboxForLogout(e){Z?.markForLogout({policy:e})}}}export{E as createImConnection};
|
|
1
|
+
import{createLoginHandler as e}from"../login/login-handler.js";import{sendExpressionMessage as t}from"../message-flow/expression/expression-message.js";import{sendGameMessage as n}from"../message-flow/game/game-message.js";import{sendGiftMessage as o}from"../message-flow/gift/gift-message.js";import{sendLiveRoomMessage as r}from"../message-flow/live-room/live-room-message.js";import{sendMiniProgramMessage as i}from"../message-flow/mini-program/mini-program-message.js";import{sendTransferMessage as a}from"../message-flow/transfer/transfer-message.js";import{createPacketRouter as s}from"../packet-router.js";import{computeBackoffDelay as d}from"./backoff.js";import{createHeartbeatManager as c}from"./heartbeat-manager.js";import{createDefaultSendStrategyRegistry as l}from"../message-flow/send/send-strategy-registry.js";import{createOutboxManager as m}from"../outbox/outbox-manager.js";import{createReadReporter as u}from"../read/read-reporter.js";import{createRecallManager as f}from"../message-flow/recall/recall-manager.js";import{createChannelMessageDeletionManager as g}from"../message-flow/recall/channel-message-deletion-manager.js";import{createRecallReceiveHandlers as p}from"../message-flow/recall/recall-receive-handlers.js";import{createEditManager as v}from"../message-flow/edit/edit-manager.js";import{createEditReceiveHandlers as h}from"../message-flow/edit/edit-receive-handlers.js";import{createMediaSender as w}from"../message-flow/media/media-sender.js";import{createDirectReadSyncCoordinator as y}from"../message-flow/read/direct-read-sync.js";import{encodeFrame as S,decodeFrameStream as I}from"../../../im-protocol/src/frame-codec.js";import{CmdId as M,ErrCode as A}from"../../../im-protocol/src/protobuf/gen/im.pub_pb.js";import{cmKickoutNotificationCodec as C}from"../../../im-protocol/src/protobuf/registry.js";import{forwardMessages as b}from"../message-flow/forward/forward-messages.js";function E(E,T={}){const{transport:k,authProvider:x,endpointProvider:P,emitter:R}=E,U=T.heartbeatIntervalMs??1e4,j=T.heartbeatMaxMissed??3,F=T.foregroundProbeTimeoutMs??5e3,O=T.loginTimeoutMs??T.readTimeoutMs??3e4,D={baseDelayMs:T.reconnect?.baseDelayMs??1e3,maxDelayMs:T.reconnect?.maxDelayMs??3e4,jitter:T.reconnect?.jitter??!0};let _,L="idle",V=!0,K=0,G=!1,$=new Uint8Array(0),B=!1,H=0,N="";function q(e){L!==e&&(E.logger?.("connection:state-transition",{from:L,to:e,selfId:N}),L=e,R.emit({type:"connection:changed",state:e}))}function Y(e){R.emit({type:"error",error:e})}function z(e,t){const n=H;e?.catch(e=>{n===H&&Y({scope:"unknown",message:t,cause:e})})}function W(e){var t;k.send((t=e,t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength))).catch(e=>{Y({scope:"transport",message:"发送失败",cause:e})})}const J=c({sendPing:()=>{W(S({command:M.SYSTEM_HEARTBEAT})),"authenticated"===L&&E.onHeartbeat?.()},onUnhealthy:()=>{E.logger?.("connection:heartbeat-unhealthy",{stateBefore:L,selfId:N}),Y({scope:"transport",message:"心跳连续未 ACK,链路判定不健康"}),pe()}},{intervalMs:U,maxMissed:j,probeTimeoutMs:F}),Q=e({authProvider:x,sendFrame:W,logger:E.logger},{timeoutMs:O}),X=E.sendStrategies??l(),Z=E.domainState?m({domainState:E.domainState,sendFrame:W,getSelfId:()=>N,isAuthenticated:()=>"authenticated"===L,sendStrategies:X,crypto:E.encryptSend?.crypto,resolvePublicKey:E.encryptSend?.resolvePublicKey,storage:E.storage,onStorageError:(e,t)=>Y({scope:"storage",message:e,cause:t}),onUpdated:e=>E.emitter.emit({type:"outbox:updated",conversation:e.conversation,item:e})},{ackTimeoutMs:T.readTimeoutMs??3e4}):void 0,ee=E.domainState?u({domainState:E.domainState,sendFrame:W,getSelfId:()=>N,isAuthenticated:()=>"authenticated"===L,emitter:R,logger:E.logger,canSendReadReceipt:E.canSendDirectReadReceipt},{readAckTimeoutMs:T.readTimeoutMs??3e4}):void 0,te=E.domainState?y({domainState:E.domainState,sendFrame:W,getSelfId:()=>N,isAuthenticated:()=>"authenticated"===L,emitter:R,logger:E.logger}):void 0,ne=E.domainState?f({domainState:E.domainState,sendFrame:W,getSelfId:()=>N,isAuthenticated:()=>"authenticated"===L,strategies:E.recallStrategies}):void 0,oe=void 0!==E.domainState&&void 0!==E.channelMessageDeletion?g({domainState:E.domainState,sendFrame:W,getSelfId:()=>N,isAuthenticated:()=>"authenticated"===L,resolveProfile:E.channelMessageDeletion.resolveProfile,onPermissionDenied:E.channelMessageDeletion.onPermissionDenied}):void 0,re=void 0!==E.domainState&&void 0!==ne?p({domainState:E.domainState,sendFrame:W,getSelfId:()=>N,onRecallAck:ne.onRecallAck,onChannelMessageDeletionAck:e=>oe?.onDeleteAck(e),logger:E.logger}):[],ie=E.domainState?v({getSelfId:()=>N,sendFrame:W,isAuthenticated:()=>"authenticated"===L,domainState:E.domainState,crypto:E.encryptSend?.crypto,resolvePublicKey:E.encryptSend?.resolvePublicKey,resolveGroupKey:E.encryptSend?.resolveGroupKey,strategies:E.editStrategies}):void 0,ae=void 0!==E.domainState&&void 0!==ie?h({onEditAck:ie.onEditAck}):[],se=void 0!==E.domainState&&void 0!==Z&&void 0!==E.media?w({getSelfId:()=>N,domainState:E.domainState,outbox:Z,mediaTransfer:E.media.transfer,mediaPreview:E.media.preview,mediaAssetCache:E.media.assetCache,onMediaAssetCacheError:E.media.onAssetCacheError,onMediaTransferError:E.media.onTransferError,onMediaAlbumContentSize:E.media.onAlbumContentSize,emitter:R,crypto:E.encryptSend?.crypto,maxConcurrentUploads:E.media.maxConcurrentUploads,recoveryPort:E.media.recoveryPort,retainFailedUploads:E.media.retainFailedUploads,shouldPersistUpload:E.media.shouldPersistUpload,waitUntilOnline:E.media.waitUntilOnline,isOnline:E.isOnline}):void 0;function de(e,t){return void 0===se?Promise.reject(new Error(`${e} 不可用:createImConnection 未注入 domainState 或 media 端口`)):""===N?Promise.reject(new Error(`${e} 需先成功登录一次以获取本端 id(尚未鉴权过)`)):t(se)}function ce(e,t,n,o){const r=E.domainState?.getConversationMessage({conversationId:n.conversationId,conversationType:n.conversationType},t);if(void 0===r||r.conversationId!==n.conversationId||r.conversationType!==n.conversationType||r.contentType!==o&&("file"!==o||"filesAlbum"!==r.contentType||1!==r.body.filesAlbum?.items.length)||"failed"!==r.status||void 0!==r.recalled||void 0!==r.deletedForEveryone||r.senderId!==N||"media.uploadInterrupted"!==r.failure?.displayCode&&"media.cancelled"!==r.failure?.displayCode&&("media.uploadTimeout"!==r.failure?.displayCode||!1!==r.failure.retryable))throw new Error(`${e} 只允许替换当前精确会话中源文件已释放的${"video"===o?"视频":"文件"}消息`);return r}const le=E.domainState&&Z?s({isActive:()=>V&&"authenticated"===L,domainState:E.domainState,outbox:Z,onReadAck:ee?.onReadAck,onSyncReadAck:te?.onAck,onSyncReadDeliver:te?.onDeliver,sendFrame:W,getSelfId:()=>N,emitter:R,logger:E.logger,decrypt:E.decrypt,commandHandlers:[...E.commandHandlers??[],...re,...ae]}):void 0;function me(){"open"!==k.state&&"connecting"!==k.state&&"closing"!==k.state||k.close().catch(()=>{})}function ue(){void 0!==_&&(clearTimeout(_),_=void 0)}async function fe(){try{return null!==(e=await x.getLoginContext())&&""!==e.userId.trim()&&""!==e.token.trim()?"available":"missing"}catch(e){return Y({scope:"login",message:"检查登录上下文失败",cause:e}),"unavailable"}var e}function ge(e,t){Y({scope:"transport",message:e,cause:t}),J.stop(),q("disconnected")}function pe(){if("reconnecting"===L||"suspended"===L)return;const e=++H;J.stop(),Q.cancel(),Z?.reset(),ee?.reset(),ne?.reset(),oe?.reset(),ie?.reset(),q("reconnecting"),me(),fe().then(t=>{"reconnecting"===L&&e===H&&("missing"!==t?function(){if(void 0!==_)return;const e=d(K,D);K+=1,_=setTimeout(()=>{_=void 0,Se()},e)}():we({code:0,reason:"token_expired"}))})}function ve(e="offline"){const t="idle"===L||"disconnected"===L||"disconnecting"===L;"offline"!==e||!t&&"suspended"!==L?(ue(),H+=1,"offline"===e&&z(se?.pauseAll(),"页面离开时暂停上传失败"),J.stop(),Q.cancel(),"session-ended"===e&&se?.cancelAll("session-ended"),Z?.reset({discardInFlight:"session-ended"===e}),ee?.reset(),ne?.reset(),oe?.reset(),ie?.reset(),t||q("suspended"),me()):z(se?.pauseAll(),"页面离开时暂停上传失败")}function he(){"suspended"===L&&V&&(!1!==E.isOnline?.()?(K=0,Se()):q("offline"))}function we(e){"idle"!==L&&"disconnected"!==L&&(E.logger?.("connection:auth-invalid-terminal",{reason:e.reason,code:`0x${e.code.toString(16)}`,stateBefore:L,selfId:N}),ue(),H+=1,J.stop(),Q.cancel(),q("disconnected"),me(),se?.cancelAll("session-ended"),Z?.reset({discardInFlight:!0}),ee?.reset(),ne?.reset(),oe?.reset(),ie?.reset(),R.emit({type:"auth:invalid",issue:e}),Promise.resolve().then(()=>x.onAuthInvalid?.(e)).catch(e=>Y({scope:"login",message:"onAuthInvalid 回调异常",cause:e})))}async function ye(){const e=await Q.login();"canceled"!==e.type&&"authenticating"===L&&function(e){switch(e.type){case"success":K=0,B=!1,e.selfId&&(N=e.selfId),q("authenticated"),J.start(),Z?.onAuthenticated(),z(se?.resumePaused(),"网络恢复后继续上传失败"),ee?.onAuthenticated(),te?.onAuthenticated(),E.readStrategies?.onAuthenticated(),E.onAuthenticated?.();break;case"auth-invalid":if("token_expired"===e.issue.reason&&0!==e.issue.code&&!B)return B=!0,Y({scope:"login",message:"token 失效,自动重试登录一次"}),void pe();we(e.issue);break;case"retry":Y(e.error),pe()}}(e)}async function Se(){if(!V)return ue(),void q("suspended");if(!1===E.isOnline?.())return ue(),J.stop(),z(se?.pauseAll("offline"),"离线探针暂停上传失败"),void q("offline");const e=++H;q("connecting"),G=!1,$=new Uint8Array(0);const t=await fe();if(e!==H)return;if("missing"===t)return void we({code:0,reason:"token_expired"});if("unavailable"===t)return void pe();let n;try{n=await P.getEndpoints()}catch(t){if(e!==H)return;return void ge("获取连接端点失败",t)}if(e!==H)return;const o=n[0];if(void 0!==o)if(function(e){try{const t=new URL(e);return"ws:"===t.protocol||"wss:"===t.protocol}catch{return!1}}(o.url)){try{await k.connect([o])}catch(t){if(e!==H)return;return Y({scope:"transport",message:"连接失败",cause:t}),void pe()}e!==H&&me()}else ge(`连接端点 URL 非法:${o.url}`);else ge("无可用连接端点(getEndpoints 返回空数组)")}function Ie(e,t,n){switch(e){case M.CM_LOGIN_ACK:Q.onLoginAck(t);break;case M.SYSTEM_HEARTBEAT_ACK:J.onAck();break;case M.CM_KICKOUT_NOTIFICATION:if(void 0!==E.logger)try{const e=C.decode(t);E.logger("connection:kickout-received",{kickedUserId:String(e.sUserId),selfId:N,matchesSelf:String(e.sUserId)===N,entryIp:e.ip,entryPort:e.port,stateBefore:L})}catch(e){E.logger("connection:kickout-decode-failed",{message:e?.message,stateBefore:L})}we({code:A.ERR_CM_AUTH_KICKEDOUT,reason:"kicked"});break;default:le?.route(e,t,{msgSeq:n})}}function Me(){return"authenticating"===L||"authenticated"===L}function Ae(e){if(!Me())return;const t=H;let n;$=function(e,t){if(0===e.length)return t;const n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}($,new Uint8Array(e));try{const e=I($);n=e.frames,$=e.remainder}catch(e){return Y({scope:"protocol",message:"帧解析失败,连接重置",cause:e}),void pe()}for(const e of n){if(!Me()||t!==H)return;Ie(e.header.command,e.body,e.header.msgSeq)}}return k.on("open",()=>{"connecting"===L&&(q("authenticating"),ye())}),k.on("message",({data:e})=>Ae(e)),k.on("error",({error:e})=>{Y({scope:"transport",message:"transport 错误",cause:e})}),k.on("close",({code:e,reason:t,wasClean:n})=>{if(J.stop(),E.logger?.("connection:transport-closed",{code:e,reason:t,wasClean:n,stateBefore:L,intentionalClose:G,nextPath:G||"disconnecting"===L?"disconnected":"idle"===L||"disconnected"===L||"reconnecting"===L||"suspended"===L||"offline"===L?"ignored":"reconnect"}),G||"disconnecting"===L)return G=!1,void q("disconnected");"idle"!==L&&"disconnected"!==L&&"reconnecting"!==L&&"suspended"!==L&&"offline"!==L&&pe()}),{get state(){return L},setConnectionAllowed(e){V!==e&&(V=e,e||ve("session-ended"))},async connect(){"connecting"!==L&&"authenticating"!==L&&"authenticated"!==L&&(ue(),K=0,await Se())},disconnect(){ue(),H+=1,J.stop(),Q.cancel(),Z?.reset(),ee?.reset(),ne?.reset(),oe?.reset(),ie?.reset(),G=!0,"idle"!==L&&"disconnected"!==L?(q("disconnecting"),"open"!==k.state&&"connecting"!==k.state&&"closing"!==k.state||k.close().catch(()=>{}),"closed"!==k.state&&"idle"!==k.state||q("disconnected")):q("disconnected")},notifyOnline(){if("offline"===L)return K=0,void Se();"reconnecting"===L&&(ue(),Se())},notifyOffline(){z(se?.pauseAll("offline"),"网络离线时暂停上传失败"),"idle"!==L&&"disconnected"!==L&&"disconnecting"!==L&&"suspended"!==L&&"offline"!==L&&(ue(),H+=1,J.stop(),Q.cancel(),Z?.reset(),ee?.reset(),ne?.reset(),oe?.reset(),ie?.reset(),q("offline"),me())},notifyVisible(){if("suspended"!==L){if("offline"===L&&!0===E.isOnline?.())return K=0,void Se();if("reconnecting"===L)return ue(),void Se();if("authenticated"===L){const e=H;fe().then(t=>{"authenticated"===L&&e===H&&("missing"!==t?J.probe():we({code:0,reason:"token_expired"}))})}}else he()},suspendForPageLifecycle:ve,resumeFromPageLifecycle:he,suppressDirectReadReceipts(e){ee?.suppress(e)},resumeDirectReadReceipts(e){ee?.resume(e)},reportDirectMediaConsumed(e,t){ee?.reportConsumedMedia(e,t),te?.reportConsumedMedia?.(e,t)},sendText(e){if(void 0===Z)throw new Error("sendText 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===N)throw new Error("sendText 需先成功登录一次以获取本端 id(尚未鉴权过)");return Z.enqueueText(e)},sendContact(e){if(void 0===Z)throw new Error("sendContact 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===N)throw new Error("sendContact 需先成功登录一次以获取本端 id(尚未鉴权过)");return Z.enqueueContact(e)},forwardMessages(e){if(void 0===Z)throw new Error("forwardMessages 不可用:createImConnection 未注入 domainState(仅连接模式)");const t=E.domainState;if(void 0===t)throw new Error("forwardMessages 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===N)throw new Error("forwardMessages 需先成功登录一次以获取本端 id(尚未鉴权过)");return b({outbox:Z,sendStrategies:X,resolveCurrentMessage:e=>t.getConversationMessage(e,e.id)},e)},recallMessage:e=>void 0===ne?Promise.reject(new Error("recallMessage 不可用:createImConnection 未注入 domainState(仅连接模式)")):ne.recall(e),deleteChannelMessageForEveryone:e=>void 0===oe?Promise.reject(new Error("deleteChannelMessageForEveryone 不可用:未装配 CHANNEL 管理员删除依赖")):oe.deleteForEveryone(e),editMessage:e=>void 0===ie?Promise.reject(new Error("editMessage 不可用:createImConnection 未注入 domainState(仅连接模式)")):ie.edit(e),sendImage:e=>de("sendImage",t=>t.sendImage(e)),sendVideo:e=>de("sendVideo",t=>t.sendVideo(e)),sendVoice:e=>de("sendVoice",t=>t.sendVoice(e)),sendFile:e=>de("sendFile",t=>t.sendFile(e)),sendGif:e=>de("sendGif",t=>t.sendGif(e)),sendMediaAlbum:e=>de("sendMediaAlbum",t=>t.sendMediaAlbum(e)),sendExpression(e){if(void 0===Z)throw new Error("sendExpression 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===N)throw new Error("sendExpression 需先成功登录一次以获取本端 id(尚未鉴权过)");return t({outbox:Z},e)},sendGame(e){if(void 0===Z)throw new Error("sendGame 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===N)throw new Error("sendGame 需先成功登录一次以获取本端 id(尚未鉴权过)");return n({outbox:Z,randomUint32:E.randomUint32},e)},sendMiniProgram(e){if(void 0===Z)throw new Error("sendMiniProgram 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===N)throw new Error("sendMiniProgram 需先成功登录一次以获取本端 id(尚未鉴权过)");return i({outbox:Z},e)},sendTransfer(e){if(void 0===Z)throw new Error("sendTransfer 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===N)throw new Error("sendTransfer 需先成功登录一次以获取本端 id(尚未鉴权过)");return a({outbox:Z},e)},sendGift(e){if(void 0===Z)throw new Error("sendGift 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===N)throw new Error("sendGift 需先成功登录一次以获取本端 id(尚未鉴权过)");return o({outbox:Z},e)},sendLiveRoom(e){if(void 0===Z)throw new Error("sendLiveRoom 不可用:createImConnection 未注入 domainState(仅连接模式)");if(""===N)throw new Error("sendLiveRoom 需先成功登录一次以获取本端 id(尚未鉴权过)");return r({outbox:Z},e)},replaceInterruptedVideo:(e,t)=>de("replaceInterruptedVideo",n=>{const o=ce("replaceInterruptedVideo",e,t,"video");return n.replaceVideo(e,o.createdAt,{...t,...void 0===t.caption&&void 0!==o.body.video?.describe?{caption:o.body.video.describe}:{},...void 0===t.refMessageId&&void 0!==o.refMessageId?{refMessageId:o.refMessageId}:{}})}),replaceInterruptedFile:(e,t)=>de("replaceInterruptedFile",n=>{const o=ce("replaceInterruptedFile",e,t,"file");return n.replaceFile(e,o.createdAt,{...t,..."filesAlbum"===o.contentType?{filesAlbum:!0,caption:o.body.filesAlbum?.caption}:{},...void 0===t.refMessageId&&void 0!==o.refMessageId?{refMessageId:o.refMessageId}:{}})}),cancelMedia(e){se?.cancel(e)},cancelMediaUpload:(e,t)=>se?.cancel(e,t)??!1,pauseMediaUpload:e=>se?.pause(e)??Promise.resolve(!1),resumeMediaUpload:e=>se?.resume(e)??!1,resumePausedMediaUploads:(e,t)=>se?.resumePaused(e,t)??Promise.resolve(),retryMediaUpload:(e,t)=>se?.retry(e,t)??!1,expireRetainedUploads(){se?.expireRetainedUploads()},invalidateMediaAssetCacheWrites(){se?.invalidateAssetCacheWrites()},async disposeMediaTasks(e){await(se?.dispose(e))},recoverMediaUpload:(e,t,n)=>void 0===se?Promise.reject(new Error("IM_MEDIA_RECOVERY_UNAVAILABLE")):de("recoverMediaUpload",o=>o.recoverUpload(e,t,n)),retryMessage(e){!0!==se?.retry(e)&&Z?.retry(e)},retryOutboxMessage:e=>Z?.retry(e)??{accepted:!1,reason:"not-found"},cancelOutboxMessage:e=>Z?.cancel(e)??{accepted:!1,reason:"not-found"},markOutboxConversationTerminated(e,t){Z?.markConversationTerminated(e,t)},clearOutboxConversationTerminated(e){Z?.clearConversationTerminated(e)},terminateConversationSending(e,t){se?.cancelConversation(e),Z?.markConversationTerminated(e,t)},settleConversationRead(e,t){if(void 0===E.domainState)throw new Error("会话已读不可用:未注入 domainState");if("direct"===e.conversationType)return E.domainState.advanceRead(e,t),void te?.report(e.conversationId);const n=E.readStrategies?.resolve(e.conversationType);if(void 0===n)throw new Error(`会话已读未支持类型:${e.conversationType}`);const o={conversationId:e.conversationId,readCursor:t};if("channel"===e.conversationType){if(void 0===n.settleConversationRead)throw new Error("CHANNEL 整会话已读尚未装配");return n.settleConversationRead(o)}return n.markRead(o)},reportVisibleMessages(e,t){if("group"!==e.conversationType&&"channel"!==e.conversationType){if("direct"!==e.conversationType)throw new Error(`可见消息回执未支持类型:${e.conversationType}`);if(void 0===ee)throw new Error("可见消息回执不可用:未注入 domainState");ee.reportVisible(e.conversationId,t)}},markRead(e,t,n){if(void 0===E.domainState)throw new Error("markRead 不可用:createImConnection 未注入 domainState(仅连接模式)");const o=n??E.domainState.getSession(e)?.type;if(void 0===o)throw new Error(`markRead 无法确定会话类型(conversationId=${e}),禁止默认 direct`);if("direct"===o){if(void 0===ee)throw new Error("markRead 不可用:createImConnection 未注入 domainState(仅连接模式)");return E.domainState.advanceRead(e,t),ee.report(e),void te?.report(e)}const r=E.readStrategies?.resolve(o);if(void 0===r)throw new Error(`markRead 暂不支持会话类型「${o}」:未注册对应已读策略,禁止 fallthrough direct`);return r.markRead({conversationId:e,readCursor:t})},sendFrame(e){W(e)},onChatAck(e){Z?.onChatAck(e)},getPendingOutbox:()=>Z?.getPending()??[],async hydrateOutbox(e){await(Z?.hydrate(e))},markOutboxForLogout(e){Z?.markForLogout({policy:e})}}}export{E as createImConnection};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{CmdId as e,ErrCode as t}from"../../../../im-protocol/src/protobuf/gen/im.pub_pb.js";import{radioChatAckCodec as r,radioChatDeliverCodec as n,radioChatCodec as o,bMessageCodec as
|
|
1
|
+
import{CmdId as e,ErrCode as t}from"../../../../im-protocol/src/protobuf/gen/im.pub_pb.js";import{radioChatAckCodec as r,radioChatDeliverCodec as n,radioChatCodec as o,bMessageCodec as c,bContentCodec as d,radioChatDeliverAckCodec as a}from"../../../../im-protocol/src/protobuf/registry.js";import{fromWireMsgId as s}from"../../mapping/message-id.js";import{buildChannelOperationNotifyRemoval as i}from"../../mapping/recall-mapper.js";import{mapIncomingChannelChat as y}from"../../mapping/channel-message-mapper.js";import{encodeFrame as l}from"../../../../im-protocol/src/frame-codec.js";function p(e,t=!0){if(e.sFromId<=0n&&""===e.botId.trim())throw new Error("channel deliver: sender id 缺失或非法");if(e.sRadioId<=0n)throw new Error("channel deliver: channel id 缺失或非法");if(""===e.sMsgId.trim())throw new Error("channel deliver: message id 缺失");if(t&&""===e.sId.trim())throw new Error("channel deliver: history cursor 缺失")}function h(h){function g(e){const n=r.decode(e),o={...""===n.sIndex?{}:{historyCursor:n.sIndex},...0n===n.nIncrId?{}:{channelSequence:n.nIncrId.toString()}},c=function(e){const r=/* @__PURE__ */new Map([[t.ERR_RADIO_DISMISS,"channelDismissed"],[t.ERR_RADIO_NOSPEAK,"channelMuted"],[t.ERR_RADIO_ISDELETE,"channelNotMember"],[t.ERR_RADIO_ADMIN,"channelAdminRequired"]]).get(e);return void 0===r?void 0:{code:e,reason:"rejected",displayCode:r,retryable:!1}}(n.errcode);h.outbox.onChatAck({id:s(n.sMsgId),serverTime:Number(n.msgTime),errcode:n.errcode,...0===Object.keys(o).length?{}:{extensions:o},...void 0===c?{}:{failure:c}});const d=function(e){switch(e){case t.ERR_RADIO_DISMISS:return{state:"dismissed",reason:"channel_dismissed"};case t.ERR_RADIO_NOSPEAK:return{state:"muted",reason:"channel_muted"};case t.ERR_RADIO_ISDELETE:return{state:"unknown_restricted",reason:"channel_not_member"};default:return}}(n.errcode);void 0!==d&&n.sRadioId>0n&&h.domainState.setChannelRestriction(n.sRadioId.toString(),d.state,d.reason),h.logger?.("channel-chat-ack",{messageId:n.sMsgId,channelId:n.sRadioId.toString(),errcode:n.errcode})}function m(e,t,r){const n=e.sRadioId.toString();h.decrypt?.onDecryptError?.({endpoint:"live",surface:t,messageId:e.sMsgId,channelId:n,encrypt:e.encrypt,payloadByteLength:e.sContent.length,...r}),h.emitter.emit({type:"error",error:{scope:"crypto",message:`CHANNEL 实时消息处理失败(${r.reason}, channelId=${n})`,...void 0===r.cause?{}:{cause:r.cause}}})}function I(e,t){let r;if(0===e.encrypt)try{r=c.decode(e.sContent)}catch(t){return void h.emitter.emit({type:"error",error:{scope:"protocol",message:`CHANNEL 实时明文 BMessage 解码失败(channelId=${e.sRadioId.toString()})`,cause:t}})}else if(1===e.encrypt&&void 0!==h.decrypt){const n=h.decrypt.resolveUserPrivateKey?.()??null;if(null===n)return void m(e,t,{reason:"no-key",decryptStage:"key-resolve",keyByteLength:0,keySource:void 0===h.decrypt.resolveUserPrivateKey?"service-absent":"miss"});let o,a;try{if(o=d.decode(e.sContent),0===o.secretKey.length||0===o.cipherData.length)throw new Error("BContent.secretKey/cipherData 缺失")}catch(r){return void m(e,t,{reason:"decrypt-failed",decryptStage:"bcontent",keyByteLength:0,keySource:"user-private-key",cause:r})}try{a=h.decrypt.crypto.decryptEndToEnd({secretKey:o.secretKey,cipherData:o.cipherData,privateKey:n})}catch(r){return void m(e,t,{reason:"decrypt-failed",decryptStage:"tea",keyByteLength:0,keySource:"user-private-key",cipherDataByteLength:o.cipherData.length,cause:r})}try{r=c.decode(a)}catch(r){return void m(e,t,{reason:"decrypt-failed",decryptStage:"bmessage",keyByteLength:0,keySource:"user-private-key",cipherDataByteLength:o.cipherData.length,decryptedByteLength:a.length,cause:r})}}else{if(2!==e.encrypt||void 0===h.decrypt)return void m(e,t,{reason:"no-key",decryptStage:"key-resolve",keyByteLength:0,keySource:"service-absent"});{const n=h.decrypt.resolveChannelKey(e.sRadioId.toString());if(null===n||16!==n.length)return void m(e,t,{reason:"no-key",decryptStage:"key-resolve",keyByteLength:n?.length??0,keySource:null===n?"miss":"cache"});let o,a;try{const t=d.decode(e.sContent);if(0===t.cipherData.length)throw new Error("BContent.cipherData 缺失");o=t.cipherData}catch(r){return void m(e,t,{reason:"decrypt-failed",decryptStage:"bcontent",keyByteLength:n.length,keySource:"cache",cause:r})}try{a=h.decrypt.crypto.decryptSymmetric({teaKey:n,cipherData:o})}catch(r){return void m(e,t,{reason:"decrypt-failed",decryptStage:"tea",keyByteLength:n.length,keySource:"cache",cipherDataByteLength:o.length,cause:r})}try{r=c.decode(a)}catch(r){return void m(e,t,{reason:"decrypt-failed",decryptStage:"bmessage",keyByteLength:n.length,keySource:"cache",cipherDataByteLength:o.length,decryptedByteLength:a.length,cause:r})}}}return r}function v(t,r){const n=h.getSelfId(),o=h.getConnectionEpoch?.(),c=()=>{void 0!==r&&!1!==h.isActive?.()&&h.getSelfId()===n&&h.getConnectionEpoch?.()===o&&function(t){const r=a.create({sFromId:t.sFromId,sRadioId:t.sRadioId,sMsgId:t.sMsgId,sIndex:t.sId});h.sendFrame(l({command:e.RADIO_CHAT_DELIVER_ACK,body:a.encode(r)}))}(r)},d=void 0===h.domainState.commitReceivedMessages?h.domainState.upsertMessages(t,"live"):h.domainState.commitReceivedMessages(t,"live");d instanceof Promise?d.then(c).catch(e=>h.emitter.emit({type:"error",error:{scope:"storage",message:"CHANNEL 消息保存或投递确认失败",cause:e}})):c()}function u(e,t){if(!1===h.isActive?.())return;const r=n.decode(t);p(r);const o=I(r,"live-deliver");if(void 0===o)return void function(e,t){const r=y(e,c.create({contentType:1,content:""}),{selfId:h.getSelfId(),cmdId:t,keepRaw:h.keepRaw,decryptFailed:!0});v([r]),1!==e.encrypt&&2!==e.encrypt||h.decrypt?.onDecryptRecovery?.({conversation:{conversationType:"channel",conversationId:r.conversationId},messageId:r.id,wireEncrypt:e.encrypt,sContent:e.sContent.slice(),cmdId:t,source:"live",createdAt:Date.now()})}(r,e);const d=i({channelId:r.sRadioId,senderId:r.sFromId,msgTime:r.msgTime,encrypt:r.encrypt},o);if(null!==d)return v([d],r),void h.logger?.("channel-operation-notify-deliver",{messageId:r.sMsgId,targetMessageId:d.id,channelId:r.sRadioId.toString(),operation:void 0!==d.deletedForEveryone?"admin-delete":"self-recall",command:e});v([y(r,o,{selfId:h.getSelfId(),cmdId:e,keepRaw:h.keepRaw})],r),h.logger?.("channel-chat-deliver",{messageId:r.sMsgId,channelId:r.sRadioId.toString(),encrypt:r.encrypt,command:e})}return[{command:e.RADIO_CHAT_ACK,handler:(e,t)=>g(t)},{command:e.RADIO_CHAT_DELIVER,handler:(e,t)=>u(e,t)},{command:e.MES_RADIO_RED_PACKET_GRABBED,handler:(e,t)=>u(e,t)},{command:e.MES_RADIO_EDIT_MSG_C2C,handler:(e,t)=>function(e,t){const r=o.decode(t);if(p(r,!1),""===r.oldMsgId.trim())throw new Error("channel edit deliver: oldMsgId 缺失");if(""===r.isEdit||"0"===r.isEdit)throw new Error("channel edit deliver: isEdit 标记缺失");if(2!==r.encrypt)throw new Error("channel edit deliver: 必须使用 CHANNEL encrypt=2");const n=s(r.oldMsgId),d=I(r,"live-edit");if(void 0===d){const t={conversationType:"channel",conversationId:r.sRadioId.toString()};return void 0===h.domainState.getConversationMessage(t,n)&&v([{...y(r,c.create({contentType:1,content:""}),{selfId:h.getSelfId(),cmdId:e,keepRaw:h.keepRaw,decryptFailed:!0,edited:!0}),id:n}]),void h.decrypt?.onDecryptRecovery?.({conversation:t,messageId:n,wireEncrypt:2,sContent:r.sContent.slice(),cmdId:e,source:"live",createdAt:Date.now()})}const a=y(r,d,{selfId:h.getSelfId(),cmdId:e,keepRaw:h.keepRaw,edited:!0});if("text"!==a.contentType)throw new Error("channel edit deliver: 仅支持 text 消息");h.domainState.editMessage({conversationType:"channel",conversationId:a.conversationId},n,a.body,a.mention),void 0===h.domainState.getConversationMessage({conversationType:"channel",conversationId:a.conversationId},n)&&v([{...a,id:n,edited:!0,extensions:{...a.extensions,editOperationMessageId:a.id,previousMessageId:n}}])}(e,t)}]}export{h as createChannelReceiveHandlers};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{encodeConversationKey as e}from"../conversation-identity.js";import{assertOutgoingContentBodyMatchesType as t}from"../mapping/content-body.js";import{normalizeStoredVideoBody as n}from"../mapping/video-body.js";import{createDefaultSendStrategyRegistry as o}from"../message-flow/send/send-strategy-registry.js";import{classifyAckFailure as s}from"../mapping/message-mapper.js";import{computeSortKey as r,computeMessageSortKey as a,resolveMessageTimestamp as i}from"../mapping/sort.js";import{describeUnsupportedConversation as d}from"../message-flow/conversation-support.js";import{newClientMessageId as c}from"../mapping/message-id.js";const u=/* @__PURE__ */new Set([32768,0]),p=/* @__PURE__ */new Set([33281,33299]),l=33298,y=/* @__PURE__ */new Set([...p,l]);function f(e){if(e instanceof Uint8Array)return e.slice();if(Array.isArray(e))return e.map(e=>f(e));if(null!==e&&"object"==typeof e){const t={};for(const[n,o]of Object.entries(e))t[n]=f(o);return t}return e}function v(e){return f(e)}function g(e){return f(e)}function m(m,b={}){const I=b.ackTimeoutMs??3e4,T=b.maxAttempts??5,h=m.now??(()=>Date.now()),M=m.sendStrategies??o(),w=/* @__PURE__ */new Map,S=/* @__PURE__ */new Map,A=/* @__PURE__ */new Map,x=/* @__PURE__ */new Map;let C=0;const E=/* @__PURE__ */new Set,k=/* @__PURE__ */new Map,q=/* @__PURE__ */new Set,O=/* @__PURE__ */new Set,F=/* @__PURE__ */new Set,j=/* @__PURE__ */new Map;function P(t){return e(t)}function R(e,t){return e.createdAt!==t.createdAt?e.createdAt-t.createdAt:e.id<t.id?-1:e.id>t.id?1:0}function U(e){const t=P(e),n=S.get(t);if(void 0!==n)return n;let o=0;for(const t of m.domainState.getMessagesByConversation({conversationType:e.conversationType,conversationId:e.conversationId}))o=Math.max(o,i(t));for(const e of w.values())P(e)===t&&(o=Math.max(o,e.createdAt));return S.set(t,o),o}function K(e,t){const n=P(e);t>(S.get(n)??U(e))&&S.set(n,t)}function D(e){const t=U(e),n=Math.max(h(),t+1);return S.set(P(e),n),{id:c(),createdAt:n}}function N(e,t){m.onUpdated?.({messageId:e.id,conversation:{conversationType:e.conversationType,conversationId:e.conversationId},state:t,...void 0===e.lastError?{}:{failure:{reason:e.lastError.reason,retryable:e.lastError.retryable}}})}function $(e){void 0!==m.storage&&m.storage.saveOutboxMessage(v(e)).catch(e=>m.onStorageError?.("Outbox 落盘失败",e))}function B(e){void 0!==m.storage&&m.storage.removeOutboxMessage(e).catch(e=>m.onStorageError?.("Outbox 删除失败",e))}function L(e){const t=A.get(e);void 0!==t&&(clearTimeout(t),A.delete(e))}function z(e,t,n){const o=!0===n?.authoritativeFailure?{authoritativeOutboxFailure:!0}:void 0,s=n?.entry??w.get(e);if(void 0===s)return;const i=m.domainState.getConversationMessage(s,e);if(void 0!==i)return void m.domainState.upsertMessages([{...i,...t}],"live",o);const d={...{id:s.id,conversationId:s.conversationId,conversationType:s.conversationType,senderId:m.getSelfId(),contentType:s.contentType,body:g(s.body),createdAt:s.createdAt,sortKey:r(s.createdAt,s.id),status:s.status,receipt:"unread",encryption:f(s.encryption),failure:void 0===s.lastError?void 0:f(s.lastError),...void 0!==s.mention?{mention:f(s.mention)}:{},...void 0!==s.refMessageId?{refMessageId:s.refMessageId}:{}},...t};m.domainState.upsertMessages([{...d,sortKey:a(d)}],"live",o)}function G(e,t){L(e);const n=w.get(e);void 0!==n&&(n.status="failed",n.lastError=t,z(e,{status:"failed",failure:t}),$(n),N(n,"failed"),J(e))}async function H(e){if(x.has(e.id))return;if(E.has(P(e)))return void G(e.id,{code:-4,reason:"unknown",displayCode:"unknown",message:"会话成员关系已终止,消息不会继续发送",retryable:!1});const t=/* @__PURE__ */Symbol("outbox-dispatch");x.set(e.id,t);const n=C;try{const t=M.resolve(e.conversationType);if(void 0===t)return void G(e.id,{code:-3,reason:"unsupported",displayCode:"conversationUnsupported",params:{type:e.conversationType},message:d(e.conversationType,"outbox.dispatch"),retryable:!1});let o;try{const s={selfId:m.getSelfId(),crypto:m.crypto,resolveEncryptionKey:m.resolvePublicKey},r=void 0===t.buildOutgoingFrames?t.buildOutgoingFrame(e,s):t.buildOutgoingFrames(e,s);if(r instanceof Uint8Array)o=[r];else if(Array.isArray(r))o=r;else{const e=await r;o=e instanceof Uint8Array?[e]:e}if(n!==C)return;if(0===o.length||o.some(e=>!(e instanceof Uint8Array)))throw new Error(`发送策略返回了非法帧序列(conversationType=${e.conversationType})`)}catch{if(n!==C)return;return e.attempts+=1,void G(e.id,{code:-2,reason:"unknown"})}if(E.has(P(e)))return void G(e.id,{code:-4,reason:"unknown",displayCode:"unknown",message:"会话成员关系已终止,消息不会继续发送",retryable:!1});if(!m.isAuthenticated())return e.status="pending",z(e.id,{status:"pending"}),$(e),void N(e,"queued");e.status="sending",e.attempts+=1,z(e.id,{status:"sending"}),$(e),N(e,"sending");for(const e of o)m.sendFrame(e);L(e.id),A.set(e.id,setTimeout(()=>G(e.id,{code:-1,reason:"timeout"}),I))}finally{x.get(e.id)===t&&x.delete(e.id)}}function J(e){const t=j.get(e);void 0!==t&&(j.delete(e),t())}function Q(e){const t=w.get(e);return void 0===t||"sending"!==t.status?Promise.resolve():new Promise(t=>j.set(e,t))}function V(e){return("pending"===e.status||"failed"===e.status)&&!("failed"===e.status&&!1===e.lastError?.retryable)&&"manual"!==e.resumePolicy&&(e.attempts<T||O.has(e.id))&&void 0!==M.resolve(e.conversationType)}function W(e,t){let n;for(const o of w.values())!t.has(o.id)&&P(o)===e&&V(o)&&(void 0===n||R(o,n)<0)&&(n=o);return n}function X(e,t=!1){const n=P(e);t&&F.add(n),k.has(n)?q.add(n):Y(n)}async function Y(e){const t=/* @__PURE__ */Symbol("outbox-drain"),n=C;k.set(e,t);try{do{q.delete(e);const t=/* @__PURE__ */new Set;for(;n===C&&m.isAuthenticated();){const o=W(e,t);if(void 0===o)break;if(t.add(o.id),O.delete(o.id),await H(o),n!==C)return;F.has(e)&&await Q(o.id)}}while(n===C&&q.has(e)&&m.isAuthenticated())}finally{k.get(e)===t&&(k.delete(e),F.delete(e))}}function Z(e,t=!1){t&&F.add(e),k.has(e)?q.add(e):Y(e)}function _(e){const t={code:-2,reason:"unknown",displayCode:"sendCanceled",retryable:!1};e.lastError=t,z(e.id,{status:"failed",failure:t}),O.delete(e.id),w.delete(e.id),B(e.id),N(e,"canceled"),J(e.id)}return{allocateMessageIdentity:D,enqueueText(e){const{id:t,createdAt:n}=D(e),o={encrypted:e.encrypted??!1},s=void 0!==M.resolve(e.conversationType),a=s&&m.isAuthenticated(),i={id:t,conversationId:e.conversationId,conversationType:e.conversationType,senderId:m.getSelfId(),contentType:"text",body:{text:e.text},createdAt:n,sortKey:r(n,t),status:"pending",receipt:"unread",encryption:f(o),...void 0!==e.mention?{mention:f(e.mention)}:{},...void 0!==e.refMessageId?{refMessageId:e.refMessageId}:{}},c={id:t,conversationId:e.conversationId,conversationType:e.conversationType,contentType:"text",body:{text:e.text},encryption:f(o),status:"pending",attempts:0,createdAt:n,...void 0!==e.mention?{mention:f(e.mention)}:{},...void 0!==e.refMessageId?{refMessageId:e.refMessageId}:{}};return w.set(t,c),$(c),N(c,"queued"),m.domainState.upsertMessages([i],"live",{newOutgoing:!0}),s?(a&&X(c),v(c)):(G(t,{code:-3,reason:"unsupported",displayCode:"conversationUnsupported",params:{type:e.conversationType},message:d(e.conversationType,"outbox.enqueueText"),retryable:!1}),v(c))},enqueueContact(e){const t=e.contact.targetId.trim(),n=e.contact.displayName.trim();if(""===t)throw new Error("outbox.enqueueContact: targetId 不能为空");if(""===n)throw new Error("outbox.enqueueContact: displayName 不能为空");if("individual"!==e.contact.kind&&"group"!==e.contact.kind&&"channel"!==e.contact.kind)throw new Error(`outbox.enqueueContact: 不支持发送 ${String(e.contact.kind)} 名片`);const{id:o,createdAt:s}=D(e),a={encrypted:e.encrypted??!1},i=void 0!==M.resolve(e.conversationType),c=i&&m.isAuthenticated(),u={contact:{...e.contact,targetId:t,displayName:n}},p={id:o,conversationId:e.conversationId,conversationType:e.conversationType,senderId:m.getSelfId(),contentType:"contact",body:g(u),createdAt:s,sortKey:r(s,o),status:"pending",receipt:"unread",encryption:f(a),...void 0===e.refMessageId?{}:{refMessageId:e.refMessageId}},l={id:o,conversationId:e.conversationId,conversationType:e.conversationType,contentType:"contact",body:g(u),encryption:f(a),status:"pending",attempts:0,createdAt:s,...void 0===e.refMessageId?{}:{refMessageId:e.refMessageId}};return w.set(o,l),$(l),N(l,"queued"),m.domainState.upsertMessages([p],"live",{newOutgoing:!0}),i?(c&&X(l),v(l)):(G(o,{code:-3,reason:"unsupported",displayCode:"conversationUnsupported",params:{type:e.conversationType},message:d(e.conversationType,"outbox.enqueueContact"),retryable:!1}),v(l))},enqueueMedia(e){const{id:n,createdAt:o}=e,s=g(e.body);t(e.contentType,s,"outbox.enqueueMedia"),K(e,o);const a=void 0!==M.resolve(e.conversationType),i=a&&m.isAuthenticated(),c={id:n,conversationId:e.conversationId,conversationType:e.conversationType,senderId:m.getSelfId(),contentType:e.contentType,body:g(s),createdAt:o,sortKey:r(o,n),status:"pending",receipt:"unread",encryption:f(e.encryption),...void 0!==e.mention?{mention:f(e.mention)}:{},...void 0!==e.refMessageId?{refMessageId:e.refMessageId}:{}},u={id:n,conversationId:e.conversationId,conversationType:e.conversationType,contentType:e.contentType,body:s,encryption:f(e.encryption),status:"pending",attempts:0,createdAt:o,...void 0!==e.mention?{mention:f(e.mention)}:{},...void 0!==e.refMessageId?{refMessageId:e.refMessageId}:{}};return w.set(n,u),$(u),N(u,"queued"),m.domainState.upsertMessages([c],"live",{newOutgoing:!0!==e.optimisticAlreadyCreated}),a?(i&&X(u),v(u)):(G(n,{code:-3,reason:"unsupported",displayCode:"conversationUnsupported",params:{type:e.conversationType},message:d(e.conversationType,"outbox.enqueueMedia"),retryable:!1}),X(u,!0),v(u))},onChatAck(e){L(e.id);const t=w.get(e.id);if(void 0!==t)if(u.has(e.errcode))w.delete(e.id),B(e.id),z(e.id,{status:"sent",serverTime:e.serverTime>0?e.serverTime:void 0,...void 0===e.extensions?{}:{extensions:{...m.domainState.getConversationMessage(t,e.id)?.extensions,...e.extensions}}},{entry:t}),N(t,"sent"),J(e.id);else{t.status="failed",t.lastError=e.failure??s(e.errcode);const n="direct"===t.conversationType&&p.has(e.errcode),o="direct"===t.conversationType&&e.errcode===l;n?t.lastError={...t.lastError,displayCode:"contactRequired",retryable:!1}:o&&(t.lastError={...t.lastError,displayCode:"messageRefused",retryable:!1}),z(e.id,{status:"failed",failure:t.lastError},{authoritativeFailure:!0}),n?m.domainState.appendDirectContactRequiredNotice(t.conversationId,t.id):o&&m.domainState.appendDirectMessageRefusedNotice(t.conversationId,t.id),$(t),N(t,"failed"),J(e.id)}else u.has(e.errcode)||function(e){if(!y.has(e.errcode))return;const t=m.getSelfId(),n=m.domainState.getMessagesById(e.id).filter(e=>"direct"===e.conversationType&&e.senderId===t);if(n.length>1)throw new Error(`DIRECT 终态 ACK 消息 ID 存在多会话歧义:${e.id}`);const o=n[0];if(void 0===o)return;const r=p.has(e.errcode),a=e.errcode===l;let i=e.failure??s(e.errcode);r?i={...i,displayCode:"contactRequired",retryable:!1}:a&&(i={...i,displayCode:"messageRefused",retryable:!1}),m.domainState.upsertMessages([{...o,status:"failed",failure:i}],"live",{authoritativeOutboxFailure:!0}),r?m.domainState.appendDirectContactRequiredNotice(o.conversationId,o.id):a&&m.domainState.appendDirectMessageRefusedNotice(o.conversationId,o.id)}(e)},onAuthenticated(){!function(){const e=/* @__PURE__ */new Set;for(const t of w.values())V(t)&&e.add(P(t));for(const t of e)Z(t,!0)}()},retry(e){const t=w.get(e);return void 0===t?{accepted:!1,reason:"not-found"}:"sending"===t.status||x.has(e)?{accepted:!1,reason:"in-flight"}:"failed"===t.status&&!1===t.lastError?.retryable?{accepted:!1,reason:"not-retryable"}:"failed"===t.status||"pending"===t.status&&"manual"===t.resumePolicy?("manual"===t.resumePolicy&&(t.resumePolicy="automatic",$(t)),O.add(t.id),X(t),{accepted:!0}):{accepted:!1,reason:"invalid-state"}},cancel(e){const t=w.get(e);return void 0===t?{accepted:!1,reason:"not-found"}:"sending"===t.status||x.has(e)?{accepted:!1,reason:"in-flight"}:"pending"!==t.status?{accepted:!1,reason:"invalid-state"}:t.attempts>0?{accepted:!1,reason:"delivery-uncertain"}:(_(t),{accepted:!0})},markConversationTerminated(e,t){const n=P(e);E.add(n);for(const e of[...w.values()])P(e)===n&&("pending"!==e.status||0!==e.attempts||x.has(e.id)?G(e.id,{code:-4,reason:"unknown",displayCode:"unknown",message:`会话成员关系已终止:${t}`,retryable:!1}):_(e))},clearConversationTerminated(e){const t=P(e);E.delete(t),Z(t)},markForLogout(e){for(const t of w.values())if("pending"===t.status||"sending"===t.status||"failed"===t.status){if(L(t.id),t.resumePolicy="manual","fail"===e.policy){const e={code:-2,reason:"unknown",displayCode:"sessionLoggedOut",retryable:!0};t.status="failed",t.lastError=e,z(t.id,{status:"failed",failure:e}),N(t,"failed")}$(t),J(t.id)}},getPending:()=>[...w.values()].map(v),reset(e){e?.discardInFlight&&(C+=1,x.clear(),k.clear(),q.clear(),F.clear());for(const e of[...A.keys()])L(e);for(const e of w.values())"sending"===e.status&&(e.status="pending",z(e.id,{status:"pending"}),$(e),N(e,"queued"),J(e.id))},async hydrate(e=()=>!0){if(void 0!==m.storage&&e())try{const o=await m.storage.getOutbox();if(!e())return;for(const s of o){if(!e())return;const o=v(s);if("sent"===o.status){B(o.id);continue}try{t(o.contentType,o.body,`outbox.hydrate(${o.id})`),void 0!==o.body.video&&(o.body={...o.body,video:n(o.body.video)})}catch(t){if(m.onStorageError?.(`Outbox 持久化条目正文损坏,已删除(id=${o.id})`,t),!e())return;if(B(o.id),void 0!==m.domainState.getConversationMessage(o,o.id)){const e={code:-2,reason:"unknown",displayCode:"unknown",message:"发送账本正文损坏,已停止重试",retryable:!1};z(o.id,{status:"failed",failure:e},{authoritativeFailure:!0,entry:o})}continue}const r="sending"===o.status?"pending":o.status,a={...o,status:r};if(w.set(o.id,a),K(a,a.createdAt),N(a,"pending"===r?"queued":r),!e())return;void 0!==m.domainState.getConversationMessage(o,o.id)&&z(o.id,{status:r,failure:void 0===o.lastError?void 0:f(o.lastError)})}}catch(t){e()&&m.onStorageError?.("Outbox 回读失败",t)}}}}export{m as createOutboxManager};
|
|
1
|
+
import{encodeConversationKey as e}from"../conversation-identity.js";import{assertOutgoingContentBodyMatchesType as t}from"../mapping/content-body.js";import{normalizeStoredVideoBody as n}from"../mapping/video-body.js";import{createDefaultSendStrategyRegistry as o}from"../message-flow/send/send-strategy-registry.js";import{classifyAckFailure as r}from"../mapping/message-mapper.js";import{computeSortKey as s,computeMessageSortKey as a,resolveMessageTimestamp as i}from"../mapping/sort.js";import{describeUnsupportedConversation as d}from"../message-flow/conversation-support.js";import{newClientMessageId as c}from"../mapping/message-id.js";const u=/* @__PURE__ */new Set([32768,0]),p=/* @__PURE__ */new Set([33281,33299]),l=33298,y=/* @__PURE__ */new Set([...p,l]);function f(e){if(e instanceof Uint8Array)return e.slice();if(Array.isArray(e))return e.map(e=>f(e));if(null!==e&&"object"==typeof e){const t={};for(const[n,o]of Object.entries(e))t[n]=f(o);return t}return e}function v(e){return f(e)}function g(e){return f(e)}function m(m,b={}){const I=b.ackTimeoutMs??3e4,T=b.maxAttempts??5,h=m.now??(()=>Date.now()),M=m.sendStrategies??o(),w=/* @__PURE__ */new Map,S=/* @__PURE__ */new Map,A=/* @__PURE__ */new Map,x=/* @__PURE__ */new Map;let C=0;const E=/* @__PURE__ */new Set,k=/* @__PURE__ */new Map,q=/* @__PURE__ */new Set,O=/* @__PURE__ */new Set,F=/* @__PURE__ */new Set,j=/* @__PURE__ */new Map;function P(t){return e(t)}function R(e,t){return e.createdAt!==t.createdAt?e.createdAt-t.createdAt:e.id<t.id?-1:e.id>t.id?1:0}function U(e){const t=P(e),n=S.get(t);if(void 0!==n)return n;let o=0;for(const t of m.domainState.getMessagesByConversation({conversationType:e.conversationType,conversationId:e.conversationId}))o=Math.max(o,i(t));for(const e of w.values())P(e)===t&&(o=Math.max(o,e.createdAt));return S.set(t,o),o}function K(e,t){const n=P(e);t>(S.get(n)??U(e))&&S.set(n,t)}function D(e){const t=U(e),n=Math.max(h(),t+1);return S.set(P(e),n),{id:c(),createdAt:n}}function N(e,t){m.onUpdated?.({messageId:e.id,conversation:{conversationType:e.conversationType,conversationId:e.conversationId},state:t,...void 0===e.lastError?{}:{failure:{reason:e.lastError.reason,retryable:e.lastError.retryable}}})}function $(e){void 0!==m.storage&&m.storage.saveOutboxMessage(v(e)).catch(e=>m.onStorageError?.("Outbox 落盘失败",e))}function B(e){void 0!==m.storage&&m.storage.removeOutboxMessage(e).catch(e=>m.onStorageError?.("Outbox 删除失败",e))}function L(e){const t=A.get(e);void 0!==t&&(clearTimeout(t),A.delete(e))}function z(e,t,n){const o=!0===n?.authoritativeFailure?{authoritativeOutboxFailure:!0}:void 0,r=n?.entry??w.get(e);if(void 0===r)return;const i=m.domainState.getConversationMessage(r,e);if(void 0!==i)return void m.domainState.upsertMessages([{...i,...t}],"live",o);const d={...{id:r.id,conversationId:r.conversationId,conversationType:r.conversationType,senderId:m.getSelfId(),contentType:r.contentType,body:g(r.body),createdAt:r.createdAt,sortKey:s(r.createdAt,r.id),status:r.status,receipt:"unread",encryption:f(r.encryption),failure:void 0===r.lastError?void 0:f(r.lastError),...void 0!==r.mention?{mention:f(r.mention)}:{},...void 0!==r.refMessageId?{refMessageId:r.refMessageId}:{}},...t};m.domainState.upsertMessages([{...d,sortKey:a(d)}],"live",o)}function G(e,t){L(e);const n=w.get(e);void 0!==n&&(n.status="failed",n.lastError=t,z(e,{status:"failed",failure:t}),$(n),N(n,"failed"),J(e))}async function H(e){if(x.has(e.id))return;if(E.has(P(e)))return void G(e.id,{code:-4,reason:"unknown",displayCode:"unknown",message:"会话成员关系已终止,消息不会继续发送",retryable:!1});const t=/* @__PURE__ */Symbol("outbox-dispatch");x.set(e.id,t);const n=C;try{const t=M.resolve(e.conversationType);if(void 0===t)return void G(e.id,{code:-3,reason:"unsupported",displayCode:"conversationUnsupported",params:{type:e.conversationType},message:d(e.conversationType,"outbox.dispatch"),retryable:!1});let o;try{const r={selfId:m.getSelfId(),crypto:m.crypto,resolveEncryptionKey:m.resolvePublicKey},s=void 0===t.buildOutgoingFrames?t.buildOutgoingFrame(e,r):t.buildOutgoingFrames(e,r);if(s instanceof Uint8Array)o=[s];else if(Array.isArray(s))o=s;else{const e=await s;o=e instanceof Uint8Array?[e]:e}if(n!==C)return;if(0===o.length||o.some(e=>!(e instanceof Uint8Array)))throw new Error(`发送策略返回了非法帧序列(conversationType=${e.conversationType})`)}catch{if(n!==C)return;return e.attempts+=1,void G(e.id,{code:-2,reason:"unknown"})}if(E.has(P(e)))return void G(e.id,{code:-4,reason:"unknown",displayCode:"unknown",message:"会话成员关系已终止,消息不会继续发送",retryable:!1});if(!m.isAuthenticated())return e.status="pending",z(e.id,{status:"pending"}),$(e),void N(e,"queued");e.status="sending",e.attempts+=1,z(e.id,{status:"sending"}),$(e),N(e,"sending");for(const e of o)m.sendFrame(e);L(e.id),A.set(e.id,setTimeout(()=>G(e.id,{code:-1,reason:"timeout"}),I))}finally{x.get(e.id)===t&&x.delete(e.id)}}function J(e){const t=j.get(e);void 0!==t&&(j.delete(e),t())}function Q(e){const t=w.get(e);return void 0===t||"sending"!==t.status?Promise.resolve():new Promise(t=>j.set(e,t))}function V(e){return("pending"===e.status||"failed"===e.status)&&!("failed"===e.status&&!1===e.lastError?.retryable)&&"manual"!==e.resumePolicy&&(e.attempts<T||O.has(e.id))&&void 0!==M.resolve(e.conversationType)}function W(e,t){let n;for(const o of w.values())!t.has(o.id)&&P(o)===e&&V(o)&&(void 0===n||R(o,n)<0)&&(n=o);return n}function X(e,t=!1){const n=P(e);t&&F.add(n),k.has(n)?q.add(n):Y(n)}async function Y(e){const t=/* @__PURE__ */Symbol("outbox-drain"),n=C;k.set(e,t);try{do{q.delete(e);const t=/* @__PURE__ */new Set;for(;n===C&&m.isAuthenticated();){const o=W(e,t);if(void 0===o)break;if(t.add(o.id),O.delete(o.id),await H(o),n!==C)return;F.has(e)&&await Q(o.id)}}while(n===C&&q.has(e)&&m.isAuthenticated())}finally{k.get(e)===t&&(k.delete(e),F.delete(e))}}function Z(e,t=!1){t&&F.add(e),k.has(e)?q.add(e):Y(e)}function _(e){const t={code:-2,reason:"unknown",displayCode:"sendCanceled",retryable:!1};e.lastError=t,z(e.id,{status:"failed",failure:t}),O.delete(e.id),w.delete(e.id),B(e.id),N(e,"canceled"),J(e.id)}return{allocateMessageIdentity:D,enqueueText(e){const{id:t,createdAt:n}=D(e),o={encrypted:e.encrypted??!1},r=void 0!==M.resolve(e.conversationType),a=r&&m.isAuthenticated(),i={id:t,conversationId:e.conversationId,conversationType:e.conversationType,senderId:m.getSelfId(),contentType:"text",body:{text:e.text},createdAt:n,sortKey:s(n,t),status:"pending",receipt:"unread",encryption:f(o),...void 0!==e.mention?{mention:f(e.mention)}:{},...void 0!==e.refMessageId?{refMessageId:e.refMessageId}:{}},c={id:t,conversationId:e.conversationId,conversationType:e.conversationType,contentType:"text",body:{text:e.text},encryption:f(o),status:"pending",attempts:0,createdAt:n,...void 0!==e.mention?{mention:f(e.mention)}:{},...void 0!==e.refMessageId?{refMessageId:e.refMessageId}:{}};return w.set(t,c),$(c),N(c,"queued"),m.domainState.upsertMessages([i],"live",{newOutgoing:!0}),r?(a&&X(c),v(c)):(G(t,{code:-3,reason:"unsupported",displayCode:"conversationUnsupported",params:{type:e.conversationType},message:d(e.conversationType,"outbox.enqueueText"),retryable:!1}),v(c))},enqueueContact(e){const t=e.contact.targetId.trim(),n=e.contact.displayName.trim();if(""===t)throw new Error("outbox.enqueueContact: targetId 不能为空");if(""===n)throw new Error("outbox.enqueueContact: displayName 不能为空");if("individual"!==e.contact.kind&&"group"!==e.contact.kind&&"channel"!==e.contact.kind&&"robot"!==e.contact.kind)throw new Error(`outbox.enqueueContact: 不支持发送 ${String(e.contact.kind)} 名片`);const{id:o,createdAt:r}=D(e),a={encrypted:e.encrypted??!1},i=void 0!==M.resolve(e.conversationType),c=i&&m.isAuthenticated(),u={contact:{...e.contact,targetId:t,displayName:n}},p={id:o,conversationId:e.conversationId,conversationType:e.conversationType,senderId:m.getSelfId(),contentType:"contact",body:g(u),createdAt:r,sortKey:s(r,o),status:"pending",receipt:"unread",encryption:f(a),...void 0===e.refMessageId?{}:{refMessageId:e.refMessageId}},l={id:o,conversationId:e.conversationId,conversationType:e.conversationType,contentType:"contact",body:g(u),encryption:f(a),status:"pending",attempts:0,createdAt:r,...void 0===e.refMessageId?{}:{refMessageId:e.refMessageId}};return w.set(o,l),$(l),N(l,"queued"),m.domainState.upsertMessages([p],"live",{newOutgoing:!0}),i?(c&&X(l),v(l)):(G(o,{code:-3,reason:"unsupported",displayCode:"conversationUnsupported",params:{type:e.conversationType},message:d(e.conversationType,"outbox.enqueueContact"),retryable:!1}),v(l))},enqueueMedia(e){const{id:n,createdAt:o}=e,r=g(e.body);t(e.contentType,r,"outbox.enqueueMedia"),K(e,o);const a=void 0!==M.resolve(e.conversationType),i=a&&m.isAuthenticated(),c={id:n,conversationId:e.conversationId,conversationType:e.conversationType,senderId:m.getSelfId(),contentType:e.contentType,body:g(r),createdAt:o,sortKey:s(o,n),status:"pending",receipt:"unread",encryption:f(e.encryption),...void 0!==e.mention?{mention:f(e.mention)}:{},...void 0!==e.refMessageId?{refMessageId:e.refMessageId}:{}},u={id:n,conversationId:e.conversationId,conversationType:e.conversationType,contentType:e.contentType,body:r,encryption:f(e.encryption),status:"pending",attempts:0,createdAt:o,...void 0!==e.mention?{mention:f(e.mention)}:{},...void 0!==e.refMessageId?{refMessageId:e.refMessageId}:{}};return w.set(n,u),$(u),N(u,"queued"),m.domainState.upsertMessages([c],"live",{newOutgoing:!0!==e.optimisticAlreadyCreated}),a?(i&&X(u),v(u)):(G(n,{code:-3,reason:"unsupported",displayCode:"conversationUnsupported",params:{type:e.conversationType},message:d(e.conversationType,"outbox.enqueueMedia"),retryable:!1}),X(u,!0),v(u))},onChatAck(e){L(e.id);const t=w.get(e.id);if(void 0!==t)if(u.has(e.errcode))w.delete(e.id),B(e.id),z(e.id,{status:"sent",serverTime:e.serverTime>0?e.serverTime:void 0,...void 0===e.extensions?{}:{extensions:{...m.domainState.getConversationMessage(t,e.id)?.extensions,...e.extensions}}},{entry:t}),N(t,"sent"),J(e.id);else{t.status="failed",t.lastError=e.failure??r(e.errcode);const n="direct"===t.conversationType&&p.has(e.errcode),o="direct"===t.conversationType&&e.errcode===l;n?t.lastError={...t.lastError,displayCode:"contactRequired",retryable:!1}:o&&(t.lastError={...t.lastError,displayCode:"messageRefused",retryable:!1}),z(e.id,{status:"failed",failure:t.lastError},{authoritativeFailure:!0}),n?m.domainState.appendDirectContactRequiredNotice(t.conversationId,t.id):o&&m.domainState.appendDirectMessageRefusedNotice(t.conversationId,t.id),$(t),N(t,"failed"),J(e.id)}else u.has(e.errcode)||function(e){if(!y.has(e.errcode))return;const t=m.getSelfId(),n=m.domainState.getMessagesById(e.id).filter(e=>"direct"===e.conversationType&&e.senderId===t);if(n.length>1)throw new Error(`DIRECT 终态 ACK 消息 ID 存在多会话歧义:${e.id}`);const o=n[0];if(void 0===o)return;const s=p.has(e.errcode),a=e.errcode===l;let i=e.failure??r(e.errcode);s?i={...i,displayCode:"contactRequired",retryable:!1}:a&&(i={...i,displayCode:"messageRefused",retryable:!1}),m.domainState.upsertMessages([{...o,status:"failed",failure:i}],"live",{authoritativeOutboxFailure:!0}),s?m.domainState.appendDirectContactRequiredNotice(o.conversationId,o.id):a&&m.domainState.appendDirectMessageRefusedNotice(o.conversationId,o.id)}(e)},onAuthenticated(){!function(){const e=/* @__PURE__ */new Set;for(const t of w.values())V(t)&&e.add(P(t));for(const t of e)Z(t,!0)}()},retry(e){const t=w.get(e);return void 0===t?{accepted:!1,reason:"not-found"}:"sending"===t.status||x.has(e)?{accepted:!1,reason:"in-flight"}:"failed"===t.status&&!1===t.lastError?.retryable?{accepted:!1,reason:"not-retryable"}:"failed"===t.status||"pending"===t.status&&"manual"===t.resumePolicy?("manual"===t.resumePolicy&&(t.resumePolicy="automatic",$(t)),O.add(t.id),X(t),{accepted:!0}):{accepted:!1,reason:"invalid-state"}},cancel(e){const t=w.get(e);return void 0===t?{accepted:!1,reason:"not-found"}:"sending"===t.status||x.has(e)?{accepted:!1,reason:"in-flight"}:"pending"!==t.status?{accepted:!1,reason:"invalid-state"}:t.attempts>0?{accepted:!1,reason:"delivery-uncertain"}:(_(t),{accepted:!0})},markConversationTerminated(e,t){const n=P(e);E.add(n);for(const e of[...w.values()])P(e)===n&&("pending"!==e.status||0!==e.attempts||x.has(e.id)?G(e.id,{code:-4,reason:"unknown",displayCode:"unknown",message:`会话成员关系已终止:${t}`,retryable:!1}):_(e))},clearConversationTerminated(e){const t=P(e);E.delete(t),Z(t)},markForLogout(e){for(const t of w.values())if("pending"===t.status||"sending"===t.status||"failed"===t.status){if(L(t.id),t.resumePolicy="manual","fail"===e.policy){const e={code:-2,reason:"unknown",displayCode:"sessionLoggedOut",retryable:!0};t.status="failed",t.lastError=e,z(t.id,{status:"failed",failure:e}),N(t,"failed")}$(t),J(t.id)}},getPending:()=>[...w.values()].map(v),reset(e){e?.discardInFlight&&(C+=1,x.clear(),k.clear(),q.clear(),F.clear());for(const e of[...A.keys()])L(e);for(const e of w.values())"sending"===e.status&&(e.status="pending",z(e.id,{status:"pending"}),$(e),N(e,"queued"),J(e.id))},async hydrate(e=()=>!0){if(void 0!==m.storage&&e())try{const o=await m.storage.getOutbox();if(!e())return;for(const r of o){if(!e())return;const o=v(r);if("sent"===o.status){B(o.id);continue}try{t(o.contentType,o.body,`outbox.hydrate(${o.id})`),void 0!==o.body.video&&(o.body={...o.body,video:n(o.body.video)})}catch(t){if(m.onStorageError?.(`Outbox 持久化条目正文损坏,已删除(id=${o.id})`,t),!e())return;if(B(o.id),void 0!==m.domainState.getConversationMessage(o,o.id)){const e={code:-2,reason:"unknown",displayCode:"unknown",message:"发送账本正文损坏,已停止重试",retryable:!1};z(o.id,{status:"failed",failure:e},{authoritativeFailure:!0,entry:o})}continue}const s="sending"===o.status?"pending":o.status,a={...o,status:s};if(w.set(o.id,a),K(a,a.createdAt),N(a,"pending"===s?"queued":s),!e())return;void 0!==m.domainState.getConversationMessage(o,o.id)&&z(o.id,{status:s,failure:void 0===o.lastError?void 0:f(o.lastError)})}}catch(t){e()&&m.onStorageError?.("Outbox 回读失败",t)}}}}export{m as createOutboxManager};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{messageDesc as A,fileDesc as g}from"@bufbuild/protobuf/codegenv2";import{file_im_pub as l}from"./im.pub_pb.js";const
|
|
1
|
+
import{messageDesc as A,fileDesc as g}from"@bufbuild/protobuf/codegenv2";import{file_im_pub as l}from"./im.pub_pb.js";const E=/* @__PURE__ */g("Cg5pbS5sb2dpbi5wcm90bxIKaW0uYXBwLnB0bCLnAQoHQ01Mb2dpbhIPCgdzVXNlcklkGAEgASgDEhMKC3NMb2dpblRva2VuGAIgASgJEhQKDHNEZXZpY2VUb2tlbhgDIAEoCRIRCgluUHVzaFR5cGUYBCABKA0SEgoKc1B1c2hUb2tlbhgFIAEoCRIUCgxzVmVyc2lvbkNvZGUYBiABKAkSEgoKc0FwbnNUb2tlbhgHIAEoCRISCgpjbGllbnRUeXBlGAggASgNEhMKC2NoYW5uZWxUeXBlGAkgASgNEhIKCmRldmljZUluZm8YCiABKAkSEgoKZGV2aWNlTmFtZRgLIAEoCSJYCgpDTUxvZ2luQWNrEg8KB3NVc2VySWQYASABKAMSIQoEbkVychgCIAEoDjITLmltLmFwcC5wdGwuRXJyQ29kZRIWCg5uTGFzdExvZ2luVGltZRgDIAEoBCJCChVDTUtpY2tvdXROb3RpZmljYXRpb24SDwoHc1VzZXJJZBgBIAEoAxIKCgJpcBgCIAEoCRIMCgRwb3J0GAMgASgNImEKD0NNUHVzaFRva2VuU3luYxIPCgdzVXNlcklkGAEgASgDEhEKCW5QdXNoVHlwZRgCIAEoDRISCgpzUHVzaFRva2VuGAMgASgJEhYKDm5QdXNoVG9rZW5UeXBlGAQgASgNIkkKE0NDTVB1c2hUb2tlblN5bmNBY2sSDwoHc1VzZXJJZBgBIAEoAxIhCgRuRXJyGAIgASgOMhMuaW0uYXBwLnB0bC5FcnJDb2RlIjAKCENNTG9nb3V0Eg8KB3NVc2VySWQYASABKAMSEwoLbkRldmljZVR5cGUYAiABKA0iQQoLQ01Mb2dvdXRBY2sSIQoEbkVychgBIAEoDjITLmltLmFwcC5wdGwuRXJyQ29kZRIPCgdzVXNlcklkGAIgASgDIowBChNDTVN5bmNBcHBQcml2YXRlS2V5Eg8KB3NGcm9tSWQYASABKAMSDQoFc1RvSWQYAiABKAMSDgoGc01zZ0lkGAMgASgJEg8KB21zZ1R5cGUYBCABKA0SDwoHY29udGVudBgFIAEoDBIPCgdtc2dUaW1lGAYgASgEEhIKCmNsaWVudFR5cGUYByABKA0iSwoTQ21TeW5jUHJpdmF0ZUtleUFjaxIPCgdzVXNlcklkGAEgASgDEhIKCmNsaWVudFR5cGUYAiABKA0SDwoHY29udGVudBgDIAEoDCJMChFLaWNrVXNlckRldmljZVJlcRIOCgZ1c2VySWQYASABKAMSEgoKY2xpZW50VHlwZRgCIAEoDRITCgtkZXZpY2VUb2tlbhgDIAEoCSIiChJLaWNrVXNlckRldmljZVJlc3ASDAoEY29kZRgBIAEoBSIsChpHZXRVc2VyT25saW5lRGV2aWNlTGlzdFJlcRIOCgZ1c2VySWQYASABKAMiUgobR2V0VXNlck9ubGluZURldmljZUxpc3RSZXNwEgwKBGNvZGUYASABKAUSJQoFaW5mb3MYAiADKAsyFi5pbS5hcHAucHRsLkRldmljZUluZm8imAEKCkRldmljZUluZm8SDgoGdXNlcklkGAEgASgDEhMKC2RldmljZVRva2VuGAIgASgJEhIKCmRldmljZU5hbWUYAyABKAkSFQoNbGFzdExvZ2luVGltZRgFIAEoAxISCgpkZXZpY2VJbmZvGAYgASgJEhIKCmNsaWVudFR5cGUYByABKAUSEgoKYXBwVmVyc2lvbhgIIAEoCSKgAQocVXNlckRldmljZU9ubGluZVN0YXR1c05vdGlmeRIOCgZ1c2VySWQYASABKAMSEgoKY2xpZW50VHlwZRgCIAEoDRIOCgZzdGF0dXMYAyABKA0SEwoLZGV2aWNlVG9rZW4YBCABKAkSDwoHY29tbWFuZBgFIAEoDRISCgpkZXZpY2VJbmZvGAYgASgJEhIKCmRldmljZU5hbWUYByABKAkiUwoNQ01DbGllbnRTdGF0ZRIPCgdzVXNlcklkGAEgASgDEg4KBm5TdGF0ZRgCIAEoDRIMCgRuU2VxGAMgASgEEhMKC25DbGllbnRUaW1lGAQgASgEInwKEENNQ2xpZW50U3RhdGVBY2sSDwoHc1VzZXJJZBgBIAEoAxIMCgRuRXJyGAIgASgFEg4KBm5TdGF0ZRgDIAEoDRIMCgRuU2VxGAQgASgEEhYKDm5Gb3JlZ3JvdW5kVHRsGAUgASgNEhMKC25TZXJ2ZXJUaW1lGAYgASgEQh8KE2NvbS5tb3NhbnQuaW0ucHJvdG9IA1oGLi4vYXBwYgZwcm90bzM",[l]),R=/* @__PURE__ */A(E,0),S=/* @__PURE__ */A(E,1),I=/* @__PURE__ */A(E,2),Z=/* @__PURE__ */A(E,3),C=/* @__PURE__ */A(E,4),V=/* @__PURE__ */A(E,15),B=/* @__PURE__ */A(E,16);export{C as CCMPushTokenSyncAckSchema,B as CMClientStateAckSchema,V as CMClientStateSchema,I as CMKickoutNotificationSchema,S as CMLoginAckSchema,R as CMLoginSchema,Z as CMPushTokenSyncSchema,E as file_im_login};
|