k2-im 0.2.16 → 0.2.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/chat-kit-pinia.d.ts +55 -11
  2. package/dist/chat-kit-vue.d.ts +5 -5
  3. package/dist/chat-kit.d.ts +101 -11
  4. package/dist/index.d.ts +104 -13
  5. package/dist/modules/im-browser/src/http/cm-http-adapter.js +1 -1
  6. package/dist/modules/im-browser/src/http/request-timeout.js +1 -0
  7. package/dist/modules/im-browser/src/http/requests/core-json-request.js +1 -1
  8. package/dist/modules/im-browser/src/http/requests/get-conversation-background-presets.js +1 -1
  9. package/dist/modules/im-browser/src/http/requests/pull-offline-channel.js +1 -1
  10. package/dist/modules/im-browser/src/media/media-download-request.js +1 -0
  11. package/dist/modules/im-browser/src/media/media-downloader.js +1 -1
  12. package/dist/modules/im-browser/src/media/media-preview-preparation-executor.js +1 -1
  13. package/dist/modules/im-browser/src/media/media-transfer-policy.js +1 -1
  14. package/dist/modules/im-browser/src/storage/indexed-db-storage-adapter.js +1 -1
  15. package/dist/modules/im-chat-kit/src/runtime/chat-runtime.js +1 -1
  16. package/dist/modules/im-chat-kit/src/runtime/media-object-url-registry.js +1 -1
  17. package/dist/modules/im-chat-kit/src/services/media.service.js +1 -1
  18. package/dist/modules/im-chat-kit/src/utils/media-transfer-presentation.js +1 -1
  19. package/dist/modules/im-core/src/mapping/group-offline-mapper.js +1 -1
  20. package/dist/modules/im-core/src/message-flow/media/media-sender.js +1 -1
  21. package/dist/modules/im-sdk/src/create-im-client.js +1 -1
  22. package/dist/modules/im-sdk/src/product/conversation-handle.js +1 -1
  23. package/dist/modules/im-sdk/src/product/media.js +1 -1
  24. package/dist/modules/im-sdk/src/runtime/history-page-size.js +1 -0
  25. package/dist/modules/im-sdk/src/runtime/local-media-preview.js +1 -1
  26. package/dist/modules/im-sdk/src/runtime/recent-history-fetcher.js +1 -1
  27. package/dist/modules/im-sdk/src/runtime/session-runtime.js +1 -1
  28. package/dist/sdk.d.ts +49 -10
  29. package/package.json +1 -1
@@ -1943,7 +1943,7 @@ interface ImHttpPort {
1943
1943
  }
1944
1944
 
1945
1945
  /** 可持久化的媒体资产类型;未注册类型必须跳过缓存,不能回退到其它类型。 */
1946
- type MediaAssetKind = 'image' | 'video' | 'file';
1946
+ type MediaAssetKind = 'image' | 'image-display' | 'video-poster' | 'video' | 'file';
1947
1947
  /** 持久媒体资产的稳定键。resourceVersion 由远端资源标识派生,避免同消息替换资源后误命中旧缓存。 */
1948
1948
  interface MediaAssetCacheKey {
1949
1949
  kind: MediaAssetKind;
@@ -1992,7 +1992,10 @@ interface MediaAssetCachePort {
1992
1992
  get: (key: MediaAssetCacheKey) => Promise<MediaAssetCacheEntry | null>;
1993
1993
  /** 按输入顺序检查完整资源是否存在且未过期;不读取 Blob、不延长闲置期限,存储故障必须抛出。 */
1994
1994
  hasMany?: (keys: readonly MediaAssetCacheKey[]) => Promise<readonly boolean[]>;
1995
- put: (entry: MediaAssetCacheEntry) => Promise<'stored' | 'skipped'>;
1995
+ /** isCurrent 在排队结束和写事务开始前复核;已失效的生成结果返回 skipped,已开始的事务不撤销。 */
1996
+ put: (entry: MediaAssetCacheEntry, options?: {
1997
+ isCurrent?: () => boolean;
1998
+ }) => Promise<'stored' | 'skipped'>;
1996
1999
  clear: () => Promise<void>;
1997
2000
  /** 删除超过闲置期限的完整持久副本;不撤销已经返回的 Blob 或宿主持有的播放地址。 */
1998
2001
  prune?: () => Promise<void>;
@@ -3036,13 +3039,13 @@ interface MediaTransferAdapterConfig {
3036
3039
  useAccelerateEndpoint?: boolean;
3037
3040
  /**
3038
3041
  * 统一允许 S3 分片上传和 Range 分段下载,默认 false(单次 PUT / 普通 GET)。
3039
- * 显式 true 后仍按 16MiB 阈值及已确认下载大小选择策略,小资源不分片。
3042
+ * 显式 true 后,上传对象达到 8 MiB 使用 Multipart;上传片长与下载段长均为 16 MiB。
3040
3043
  * 开启前各桶须支持分片请求方法,并暴露上传 ETag、下载 Content-Range 与强 ETag。
3041
3044
  * @example { multipartTransfer: true } 同时允许大资源分片上传、下载。
3042
3045
  */
3043
3046
  multipartTransfer?: boolean;
3044
3047
  /**
3045
- * 总开关开启后,是否允许超过分片阈值(16MiB)的上传使用 S3 分片上传。
3048
+ * 总开关开启后,是否允许达到分片阈值(8 MiB)的上传使用 S3 分片上传。
3046
3049
  *
3047
3050
  * 分片相比单次 PUT 需要各物理桶的 CORS 额外放行 POST(Create/CompleteMultipartUpload)、
3048
3051
  * DELETE(AbortMultipartUpload)并 `ExposeHeaders: ETag`;未配齐时分片会直接失败。
@@ -3058,8 +3061,8 @@ interface MediaTransferAdapterConfig {
3058
3061
  /**
3059
3062
  * 媒体发送阶段的并发上限;由 im-core 消费,限制媒体任务数而非分片请求数。
3060
3063
  *
3061
- * 并发按媒体体积分两档:不超过分片阈值(16 MiB)的非视频媒体走小文件档,
3062
- * 缺省 5;视频与超过阈值(或字节数未知)的内容走大文件档,缺省 3。
3064
+ * 并发按媒体体积分两档:小于分片阈值(8 MiB)的非视频媒体走小文件档,
3065
+ * 缺省 5;视频与达到阈值(或字节数未知)的内容走大文件档,缺省 3。
3063
3066
  * 分档只限制媒体任务数;实际 PUT/UploadPart 另受 adapter 的六路数据请求限制。
3064
3067
  * 两档都只接受 1-6 的整数,超出范围由 core 显式报错。
3065
3068
  * - 传一个数字:所有媒体共用这一个并发数,与分档前的语义一致。
@@ -5592,16 +5595,26 @@ interface ImMediaTasksApi {
5592
5595
  includeDisplayPoster?: boolean;
5593
5596
  }) => Promise<(TKind extends 'video' ? LocalVideoPreviewMetadata : ImagePreviewMetadata) | null>;
5594
5597
  /**
5595
- * 从本地视频提取仅供页面展示的高清 JPEG 封面,不上传、不下载、不写缓存。
5598
+ * 从本地视频或已有截图生成气泡封面;传入消息身份时复用独立持久缓存,不下载或上传。
5596
5599
  *
5597
5600
  * 长边最多 960px 且不放大原视频;与发送预读共用同一解码执行器。返回 Blob 由宿主创建和释放
5598
5601
  * object URL,不能作为 localPreviewMetadata 发进消息正文。读取失败返回 null 并记录诊断;
5599
5602
  * 宿主取消抛 AbortError,运行时失效或未装配能力时抛与 prepareLocalPreview 相同的明确错误。
5600
- * @param input.file 本地或已解密的完整视频 Blob。
5603
+ * @param input.file 本地或已解密的完整视频 Blob;已有 poster 时可以不传。
5604
+ * @param input.poster 发送前已经提取的截图,避免重新加载视频抽帧。
5605
+ * @param input.message 可选消息身份,用于持久保存封面。
5606
+ * @param input.expectedResourceUrl 取得源文件前的资源地址,防止换图后的旧结果污染缓存。
5601
5607
  * @param input.signal 页面卸载、换源或切会话时取消这次抽帧。
5602
5608
  */
5603
5609
  prepareLocalVideoPoster: (input: {
5604
- file: Blob;
5610
+ file?: Blob;
5611
+ poster?: Blob;
5612
+ message?: ImMessageRef;
5613
+ expectedResourceUrl?: string;
5614
+ signal?: AbortSignal;
5615
+ }) => Promise<Blob | null>;
5616
+ /** 只读视频气泡封面缓存;不下载、不抽帧,未命中返回 null。 */
5617
+ getCachedVideoPoster: (message: ImMessageRef, options?: {
5605
5618
  signal?: AbortSignal;
5606
5619
  }) => Promise<Blob | null>;
5607
5620
  /**
@@ -5617,6 +5630,34 @@ interface ImMediaTasksApi {
5617
5630
  file: Blob;
5618
5631
  signal?: AbortSignal;
5619
5632
  }) => Promise<Blob | null>;
5633
+ /**
5634
+ * 从本机原图生成独立的静态显示图,供 PC/H5 气泡使用;不下载、不上传、不改原图与消息尺寸。
5635
+ * 传入消息引用时先查独立的显示图缓存;稳定远端资源的结果可持久保存,本地待上传资源只生成。
5636
+ * 所有浏览器可解码格式均处理;最长边不超过 maxSize 且不放大,透明图优先保留透明度。
5637
+ * WebP 质量 0.85,最低 0.82,目标 256 KiB、最多 512 KiB;超过字节预算时可继续缩小,失败返回 null 并记录诊断。
5638
+ * 取消、账号失效、能力缺失和非法参数明确拒绝;返回 Blob 的 object URL 由宿主管理。
5639
+ * @param input.file 原始或已解密的完整图片 Blob,不会被修改。
5640
+ * @param input.maxSize 显示图最长边上限,必须是 1 到 2048 的整数。
5641
+ * @param input.signal 页面退出、资源失效时取消准备。
5642
+ * @param input.message 可选的精确消息引用,用于按消息、合集项、资源版本和尺寸隔离显示图缓存。
5643
+ * @param input.expectedResourceUrl 取得 file 前记录的消息资源地址;与 message 配合使用,不匹配时返回 null,防止旧文件写入新资源缓存。
5644
+ * @example const display = await client.media.prepareLocalImageDisplay({ file: original, maxSize: 1440 })
5645
+ */
5646
+ prepareLocalImageDisplay: (input: {
5647
+ file: Blob;
5648
+ maxSize: number;
5649
+ message?: ImMessageRef;
5650
+ expectedResourceUrl?: string;
5651
+ signal?: AbortSignal;
5652
+ }) => Promise<Blob | null>;
5653
+ /**
5654
+ * 仅读取指定消息和尺寸的持久显示图,不下载原图、不编码;未命中或读取期间资源失效返回 null。
5655
+ * maxSize 必须是 1 到 2048 的整数;取消、账号失效、存储读取失败明确拒绝。
5656
+ */
5657
+ getCachedImageDisplay: (message: ImMessageRef, options: {
5658
+ maxSize: number;
5659
+ signal?: AbortSignal;
5660
+ }) => Promise<Blob | null>;
5620
5661
  }
5621
5662
 
5622
5663
  /**
@@ -6296,7 +6337,7 @@ interface ImSettingsApi {
6296
6337
  * 1 小时、按服务端过期时间提前 5 分钟失效)、同桶并发请求复用和失败后重新签发由 SDK 负责,宿主只需提供「打一次接口」的纯函数。
6297
6338
  *
6298
6339
  * 默认单次 PUT/GET;仅 multipartTransfer=true 才允许大资源分片上传、下载。
6299
- * 各 bucket 需在对象存储侧配置 CORS 允许本站 origin 的 PUT + GET;开启分片后,超过 16MiB 的上传另需放行
6340
+ * 各 bucket 需在对象存储侧配置 CORS 允许本站 origin 的 PUT + GET;开启分片后,达到 8 MiB 的上传另需放行
6300
6341
  * POST(Create/CompleteMultipartUpload)、DELETE(AbortMultipartUpload)并 ExposeHeaders: ETag。CORS 未配齐时
6301
6342
  * 下载还需暴露 Content-Range 与强 ETag;multipartTransfer=false 统一关闭分片上传和下载。
6302
6343
  * ⚠ 并发字段只由 SDK core 的媒体编排消费;adapter 会忽略该字段。高内存设备可设置 5-6,低内存设备建议 2-3。
@@ -7155,6 +7196,8 @@ interface ChatMediaMessageRef {
7155
7196
  * 后绑定的一格把先绑定的挤掉并撤销其地址。单媒体消息不传这个字段。
7156
7197
  */
7157
7198
  itemIndex?: number;
7199
+ /** 查询时校验当前正文资源地址;不匹配即未命中,不根据页面历史推断租约身份。 */
7200
+ resourceUrl?: string;
7158
7201
  }
7159
7202
  /**
7160
7203
  * Chat Kit 提供给共享 Store 和业务 Service 的账号运行接口。
@@ -7347,8 +7390,9 @@ interface ChatRuntime {
7347
7390
  * 媒体上传成功并获得远端资源后,结束本地预览的“上传源”职责。
7348
7391
  *
7349
7392
  * 图片和视频保留为可淘汰本地缓存,使发送者短时间内查看无需重新下载;GIF 直接释放。
7393
+ * resourceUrl 指定上传完成后的正文地址,用于绑定源文件身份;后续换地址会移除旧缓存。
7350
7394
  */
7351
- resolveMediaPreviewToRemote: (ref: ChatMediaMessageRef, contentType: 'image' | 'video' | 'sticker', byteSize?: number) => void;
7395
+ resolveMediaPreviewToRemote: (ref: ChatMediaMessageRef, contentType: 'image' | 'video' | 'sticker', byteSize?: number, resourceUrl?: string) => void;
7352
7396
  /** 为指定消息取得本地媒体播放租约;没有本地缓存时返回 `undefined`,调用方应改用远端资源。 */
7353
7397
  acquireMediaBlob: (ref: ChatMediaMessageRef) => MediaObjectUrlLease | undefined;
7354
7398
  /** 只读检查完整本地媒体是否可用,不取得租约、不改变缓存淘汰顺序。 */
@@ -1272,13 +1272,13 @@ interface MediaTransferAdapterConfig {
1272
1272
  useAccelerateEndpoint?: boolean;
1273
1273
  /**
1274
1274
  * 统一允许 S3 分片上传和 Range 分段下载,默认 false(单次 PUT / 普通 GET)。
1275
- * 显式 true 后仍按 16MiB 阈值及已确认下载大小选择策略,小资源不分片。
1275
+ * 显式 true 后,上传对象达到 8 MiB 使用 Multipart;上传片长与下载段长均为 16 MiB。
1276
1276
  * 开启前各桶须支持分片请求方法,并暴露上传 ETag、下载 Content-Range 与强 ETag。
1277
1277
  * @example { multipartTransfer: true } 同时允许大资源分片上传、下载。
1278
1278
  */
1279
1279
  multipartTransfer?: boolean;
1280
1280
  /**
1281
- * 总开关开启后,是否允许超过分片阈值(16MiB)的上传使用 S3 分片上传。
1281
+ * 总开关开启后,是否允许达到分片阈值(8 MiB)的上传使用 S3 分片上传。
1282
1282
  *
1283
1283
  * 分片相比单次 PUT 需要各物理桶的 CORS 额外放行 POST(Create/CompleteMultipartUpload)、
1284
1284
  * DELETE(AbortMultipartUpload)并 `ExposeHeaders: ETag`;未配齐时分片会直接失败。
@@ -1294,8 +1294,8 @@ interface MediaTransferAdapterConfig {
1294
1294
  /**
1295
1295
  * 媒体发送阶段的并发上限;由 im-core 消费,限制媒体任务数而非分片请求数。
1296
1296
  *
1297
- * 并发按媒体体积分两档:不超过分片阈值(16 MiB)的非视频媒体走小文件档,
1298
- * 缺省 5;视频与超过阈值(或字节数未知)的内容走大文件档,缺省 3。
1297
+ * 并发按媒体体积分两档:小于分片阈值(8 MiB)的非视频媒体走小文件档,
1298
+ * 缺省 5;视频与达到阈值(或字节数未知)的内容走大文件档,缺省 3。
1299
1299
  * 分档只限制媒体任务数;实际 PUT/UploadPart 另受 adapter 的六路数据请求限制。
1300
1300
  * 两档都只接受 1-6 的整数,超出范围由 core 显式报错。
1301
1301
  * - 传一个数字:所有媒体共用这一个并发数,与分档前的语义一致。
@@ -1581,7 +1581,7 @@ type ImRequestErrorHandler = (issue: ImRequestError) => void | Promise<void>;
1581
1581
  * 1 小时、按服务端过期时间提前 5 分钟失效)、同桶并发请求复用和失败后重新签发由 SDK 负责,宿主只需提供「打一次接口」的纯函数。
1582
1582
  *
1583
1583
  * 默认单次 PUT/GET;仅 multipartTransfer=true 才允许大资源分片上传、下载。
1584
- * 各 bucket 需在对象存储侧配置 CORS 允许本站 origin 的 PUT + GET;开启分片后,超过 16MiB 的上传另需放行
1584
+ * 各 bucket 需在对象存储侧配置 CORS 允许本站 origin 的 PUT + GET;开启分片后,达到 8 MiB 的上传另需放行
1585
1585
  * POST(Create/CompleteMultipartUpload)、DELETE(AbortMultipartUpload)并 ExposeHeaders: ETag。CORS 未配齐时
1586
1586
  * 下载还需暴露 Content-Range 与强 ETag;multipartTransfer=false 统一关闭分片上传和下载。
1587
1587
  * ⚠ 并发字段只由 SDK core 的媒体编排消费;adapter 会忽略该字段。高内存设备可设置 5-6,低内存设备建议 2-3。
@@ -1940,7 +1940,7 @@ interface ImHttpPort {
1940
1940
  }
1941
1941
 
1942
1942
  /** 可持久化的媒体资产类型;未注册类型必须跳过缓存,不能回退到其它类型。 */
1943
- type MediaAssetKind = 'image' | 'video' | 'file';
1943
+ type MediaAssetKind = 'image' | 'image-display' | 'video-poster' | 'video' | 'file';
1944
1944
  /** 持久媒体资产的稳定键。resourceVersion 由远端资源标识派生,避免同消息替换资源后误命中旧缓存。 */
1945
1945
  interface MediaAssetCacheKey {
1946
1946
  kind: MediaAssetKind;
@@ -1989,7 +1989,10 @@ interface MediaAssetCachePort {
1989
1989
  get: (key: MediaAssetCacheKey) => Promise<MediaAssetCacheEntry | null>;
1990
1990
  /** 按输入顺序检查完整资源是否存在且未过期;不读取 Blob、不延长闲置期限,存储故障必须抛出。 */
1991
1991
  hasMany?: (keys: readonly MediaAssetCacheKey[]) => Promise<readonly boolean[]>;
1992
- put: (entry: MediaAssetCacheEntry) => Promise<'stored' | 'skipped'>;
1992
+ /** isCurrent 在排队结束和写事务开始前复核;已失效的生成结果返回 skipped,已开始的事务不撤销。 */
1993
+ put: (entry: MediaAssetCacheEntry, options?: {
1994
+ isCurrent?: () => boolean;
1995
+ }) => Promise<'stored' | 'skipped'>;
1993
1996
  clear: () => Promise<void>;
1994
1997
  /** 删除超过闲置期限的完整持久副本;不撤销已经返回的 Blob 或宿主持有的播放地址。 */
1995
1998
  prune?: () => Promise<void>;
@@ -3145,13 +3148,13 @@ interface MediaTransferAdapterConfig {
3145
3148
  useAccelerateEndpoint?: boolean;
3146
3149
  /**
3147
3150
  * 统一允许 S3 分片上传和 Range 分段下载,默认 false(单次 PUT / 普通 GET)。
3148
- * 显式 true 后仍按 16MiB 阈值及已确认下载大小选择策略,小资源不分片。
3151
+ * 显式 true 后,上传对象达到 8 MiB 使用 Multipart;上传片长与下载段长均为 16 MiB。
3149
3152
  * 开启前各桶须支持分片请求方法,并暴露上传 ETag、下载 Content-Range 与强 ETag。
3150
3153
  * @example { multipartTransfer: true } 同时允许大资源分片上传、下载。
3151
3154
  */
3152
3155
  multipartTransfer?: boolean;
3153
3156
  /**
3154
- * 总开关开启后,是否允许超过分片阈值(16MiB)的上传使用 S3 分片上传。
3157
+ * 总开关开启后,是否允许达到分片阈值(8 MiB)的上传使用 S3 分片上传。
3155
3158
  *
3156
3159
  * 分片相比单次 PUT 需要各物理桶的 CORS 额外放行 POST(Create/CompleteMultipartUpload)、
3157
3160
  * DELETE(AbortMultipartUpload)并 `ExposeHeaders: ETag`;未配齐时分片会直接失败。
@@ -3167,8 +3170,8 @@ interface MediaTransferAdapterConfig {
3167
3170
  /**
3168
3171
  * 媒体发送阶段的并发上限;由 im-core 消费,限制媒体任务数而非分片请求数。
3169
3172
  *
3170
- * 并发按媒体体积分两档:不超过分片阈值(16 MiB)的非视频媒体走小文件档,
3171
- * 缺省 5;视频与超过阈值(或字节数未知)的内容走大文件档,缺省 3。
3173
+ * 并发按媒体体积分两档:小于分片阈值(8 MiB)的非视频媒体走小文件档,
3174
+ * 缺省 5;视频与达到阈值(或字节数未知)的内容走大文件档,缺省 3。
3172
3175
  * 分档只限制媒体任务数;实际 PUT/UploadPart 另受 adapter 的六路数据请求限制。
3173
3176
  * 两档都只接受 1-6 的整数,超出范围由 core 显式报错。
3174
3177
  * - 传一个数字:所有媒体共用这一个并发数,与分档前的语义一致。
@@ -5703,16 +5706,26 @@ interface ImMediaTasksApi {
5703
5706
  includeDisplayPoster?: boolean;
5704
5707
  }) => Promise<(TKind extends 'video' ? LocalVideoPreviewMetadata : ImagePreviewMetadata) | null>;
5705
5708
  /**
5706
- * 从本地视频提取仅供页面展示的高清 JPEG 封面,不上传、不下载、不写缓存。
5709
+ * 从本地视频或已有截图生成气泡封面;传入消息身份时复用独立持久缓存,不下载或上传。
5707
5710
  *
5708
5711
  * 长边最多 960px 且不放大原视频;与发送预读共用同一解码执行器。返回 Blob 由宿主创建和释放
5709
5712
  * object URL,不能作为 localPreviewMetadata 发进消息正文。读取失败返回 null 并记录诊断;
5710
5713
  * 宿主取消抛 AbortError,运行时失效或未装配能力时抛与 prepareLocalPreview 相同的明确错误。
5711
- * @param input.file 本地或已解密的完整视频 Blob。
5714
+ * @param input.file 本地或已解密的完整视频 Blob;已有 poster 时可以不传。
5715
+ * @param input.poster 发送前已经提取的截图,避免重新加载视频抽帧。
5716
+ * @param input.message 可选消息身份,用于持久保存封面。
5717
+ * @param input.expectedResourceUrl 取得源文件前的资源地址,防止换图后的旧结果污染缓存。
5712
5718
  * @param input.signal 页面卸载、换源或切会话时取消这次抽帧。
5713
5719
  */
5714
5720
  prepareLocalVideoPoster: (input: {
5715
- file: Blob;
5721
+ file?: Blob;
5722
+ poster?: Blob;
5723
+ message?: ImMessageRef;
5724
+ expectedResourceUrl?: string;
5725
+ signal?: AbortSignal;
5726
+ }) => Promise<Blob | null>;
5727
+ /** 只读视频气泡封面缓存;不下载、不抽帧,未命中返回 null。 */
5728
+ getCachedVideoPoster: (message: ImMessageRef, options?: {
5716
5729
  signal?: AbortSignal;
5717
5730
  }) => Promise<Blob | null>;
5718
5731
  /**
@@ -5728,6 +5741,34 @@ interface ImMediaTasksApi {
5728
5741
  file: Blob;
5729
5742
  signal?: AbortSignal;
5730
5743
  }) => Promise<Blob | null>;
5744
+ /**
5745
+ * 从本机原图生成独立的静态显示图,供 PC/H5 气泡使用;不下载、不上传、不改原图与消息尺寸。
5746
+ * 传入消息引用时先查独立的显示图缓存;稳定远端资源的结果可持久保存,本地待上传资源只生成。
5747
+ * 所有浏览器可解码格式均处理;最长边不超过 maxSize 且不放大,透明图优先保留透明度。
5748
+ * WebP 质量 0.85,最低 0.82,目标 256 KiB、最多 512 KiB;超过字节预算时可继续缩小,失败返回 null 并记录诊断。
5749
+ * 取消、账号失效、能力缺失和非法参数明确拒绝;返回 Blob 的 object URL 由宿主管理。
5750
+ * @param input.file 原始或已解密的完整图片 Blob,不会被修改。
5751
+ * @param input.maxSize 显示图最长边上限,必须是 1 到 2048 的整数。
5752
+ * @param input.signal 页面退出、资源失效时取消准备。
5753
+ * @param input.message 可选的精确消息引用,用于按消息、合集项、资源版本和尺寸隔离显示图缓存。
5754
+ * @param input.expectedResourceUrl 取得 file 前记录的消息资源地址;与 message 配合使用,不匹配时返回 null,防止旧文件写入新资源缓存。
5755
+ * @example const display = await client.media.prepareLocalImageDisplay({ file: original, maxSize: 1440 })
5756
+ */
5757
+ prepareLocalImageDisplay: (input: {
5758
+ file: Blob;
5759
+ maxSize: number;
5760
+ message?: ImMessageRef;
5761
+ expectedResourceUrl?: string;
5762
+ signal?: AbortSignal;
5763
+ }) => Promise<Blob | null>;
5764
+ /**
5765
+ * 仅读取指定消息和尺寸的持久显示图,不下载原图、不编码;未命中或读取期间资源失效返回 null。
5766
+ * maxSize 必须是 1 到 2048 的整数;取消、账号失效、存储读取失败明确拒绝。
5767
+ */
5768
+ getCachedImageDisplay: (message: ImMessageRef, options: {
5769
+ maxSize: number;
5770
+ signal?: AbortSignal;
5771
+ }) => Promise<Blob | null>;
5731
5772
  }
5732
5773
 
5733
5774
  /**
@@ -6414,7 +6455,7 @@ interface ImEmojiCatalogEntry {
6414
6455
  * 1 小时、按服务端过期时间提前 5 分钟失效)、同桶并发请求复用和失败后重新签发由 SDK 负责,宿主只需提供「打一次接口」的纯函数。
6415
6456
  *
6416
6457
  * 默认单次 PUT/GET;仅 multipartTransfer=true 才允许大资源分片上传、下载。
6417
- * 各 bucket 需在对象存储侧配置 CORS 允许本站 origin 的 PUT + GET;开启分片后,超过 16MiB 的上传另需放行
6458
+ * 各 bucket 需在对象存储侧配置 CORS 允许本站 origin 的 PUT + GET;开启分片后,达到 8 MiB 的上传另需放行
6418
6459
  * POST(Create/CompleteMultipartUpload)、DELETE(AbortMultipartUpload)并 ExposeHeaders: ETag。CORS 未配齐时
6419
6460
  * 下载还需暴露 Content-Range 与强 ETag;multipartTransfer=false 统一关闭分片上传和下载。
6420
6461
  * ⚠ 并发字段只由 SDK core 的媒体编排消费;adapter 会忽略该字段。高内存设备可设置 5-6,低内存设备建议 2-3。
@@ -7702,6 +7743,8 @@ interface ChatMediaMessageRef {
7702
7743
  * 后绑定的一格把先绑定的挤掉并撤销其地址。单媒体消息不传这个字段。
7703
7744
  */
7704
7745
  itemIndex?: number;
7746
+ /** 查询时校验当前正文资源地址;不匹配即未命中,不根据页面历史推断租约身份。 */
7747
+ resourceUrl?: string;
7705
7748
  }
7706
7749
  /**
7707
7750
  * Chat Kit 提供给共享 Store 和业务 Service 的账号运行接口。
@@ -7894,8 +7937,9 @@ interface ChatRuntime {
7894
7937
  * 媒体上传成功并获得远端资源后,结束本地预览的“上传源”职责。
7895
7938
  *
7896
7939
  * 图片和视频保留为可淘汰本地缓存,使发送者短时间内查看无需重新下载;GIF 直接释放。
7940
+ * resourceUrl 指定上传完成后的正文地址,用于绑定源文件身份;后续换地址会移除旧缓存。
7897
7941
  */
7898
- resolveMediaPreviewToRemote: (ref: ChatMediaMessageRef, contentType: 'image' | 'video' | 'sticker', byteSize?: number) => void;
7942
+ resolveMediaPreviewToRemote: (ref: ChatMediaMessageRef, contentType: 'image' | 'video' | 'sticker', byteSize?: number, resourceUrl?: string) => void;
7899
7943
  /** 为指定消息取得本地媒体播放租约;没有本地缓存时返回 `undefined`,调用方应改用远端资源。 */
7900
7944
  acquireMediaBlob: (ref: ChatMediaMessageRef) => MediaObjectUrlLease | undefined;
7901
7945
  /** 只读检查完整本地媒体是否可用,不取得租约、不改变缓存淘汰顺序。 */
@@ -8284,6 +8328,38 @@ type GifFileClassification = 'gif' | 'not-gif' | 'invalid-gif';
8284
8328
  declare function classifyGifFile(file: Blob): Promise<GifFileClassification>;
8285
8329
  declare function isGifFile(file: Blob): Promise<boolean>;
8286
8330
 
8331
+ /** 气泡显示图的像素规格;两端共用,完整原图和消息内嵌缩略图不使用此预算。 */
8332
+ declare function resolveImageDisplayMaxSize(message: ImMessageView, itemIndex?: number): number;
8333
+ /**
8334
+ * 从借用的本机原图生成独立气泡地址。不会撤销输入 URL,也不会触发远端下载。
8335
+ * identity 让 SDK 按完整资源身份复用持久显示缓存;调用方负责撤销返回的 URL。
8336
+ * 预览必须继续使用原图,不能使用此方法的返回值。
8337
+ */
8338
+ declare function prepareImageDisplayObjectUrl(runtime: ChatRuntime, url: string, maxSize: number, signal?: AbortSignal, identity?: {
8339
+ message: ImMessageView;
8340
+ itemIndex?: number;
8341
+ }): Promise<string | null>;
8342
+ /**
8343
+ * 气泡优先读持久显示图;未命中才用已缓存的原图生成,不发起网络下载。
8344
+ * 仅产生一个由调用方拥有的显示 URL,整个过程不创建或持有原图 URL。
8345
+ */
8346
+ declare function loadCachedImageDisplayObjectUrl(runtime: ChatRuntime, message: ImMessageView, itemIndex?: number, signal?: AbortSignal): Promise<string | null>;
8347
+ /**
8348
+ * 自动加载气泡显示图:优先恢复派生缓存或本机原图,均未命中才下载。
8349
+ * 原图地址只在生成期间持有并始终释放;返回的独立显示地址归宿主。
8350
+ * 显示缓存命中即可满足气泡,完整原件已被淘汰时留待用户预览再下载。
8351
+ */
8352
+ declare function loadImageDisplayObjectUrl(runtime: ChatRuntime, message: ImMessageView, hooks: ServiceNoteHooks, options: ImMediaDownloadOptions, itemIndex?: number): Promise<string | null>;
8353
+ /**
8354
+ * 借用本机视频地址或发送前截图生成气泡封面,优先命中持久缓存。
8355
+ * 不触发远端下载;输入地址仍归调用方,返回的封面地址由调用方释放。
8356
+ */
8357
+ declare function prepareVideoPosterObjectUrl(runtime: ChatRuntime, url: string, signal?: AbortSignal, identity?: {
8358
+ message: ImMessageView;
8359
+ itemIndex?: number;
8360
+ }, poster?: Blob): Promise<string | null>;
8361
+ /** 只恢复本机视频封面:先读派生缓存,未命中才读完整视频并抽帧;不触发视频下载。 */
8362
+ declare function loadCachedVideoPosterObjectUrl(runtime: ChatRuntime, message: ImMessageView, itemIndex?: number, signal?: AbortSignal): Promise<string | null>;
8287
8363
  /**
8288
8364
  * 将用户最后预览的媒体项交给 SDK 提高下载优先级,不创建任务或持有页面资源。
8289
8365
  * 在异步查缓存、加载 URL 之前调用,重复打开已有下载也会更新优先级。
@@ -8401,31 +8477,43 @@ declare function loadFileObjectUrl(runtime: ChatRuntime, message: ImMessageView,
8401
8477
  declare const media_service_acquireMediaBlob: typeof acquireMediaBlob;
8402
8478
  declare const media_service_detectImageMime: typeof detectImageMime;
8403
8479
  declare const media_service_detectVideoMime: typeof detectVideoMime;
8480
+ declare const media_service_loadCachedImageDisplayObjectUrl: typeof loadCachedImageDisplayObjectUrl;
8404
8481
  declare const media_service_loadCachedImageObjectUrl: typeof loadCachedImageObjectUrl;
8405
8482
  declare const media_service_loadCachedMediaAlbumItemObjectUrl: typeof loadCachedMediaAlbumItemObjectUrl;
8406
8483
  declare const media_service_loadCachedVideoObjectUrl: typeof loadCachedVideoObjectUrl;
8484
+ declare const media_service_loadCachedVideoPosterObjectUrl: typeof loadCachedVideoPosterObjectUrl;
8407
8485
  declare const media_service_loadFileObjectUrl: typeof loadFileObjectUrl;
8486
+ declare const media_service_loadImageDisplayObjectUrl: typeof loadImageDisplayObjectUrl;
8408
8487
  declare const media_service_loadImageObjectUrl: typeof loadImageObjectUrl;
8409
8488
  declare const media_service_loadMediaAlbumItemObjectUrl: typeof loadMediaAlbumItemObjectUrl;
8410
8489
  declare const media_service_loadVideoObjectUrl: typeof loadVideoObjectUrl;
8411
8490
  declare const media_service_loadVoiceBytes: typeof loadVoiceBytes;
8491
+ declare const media_service_prepareImageDisplayObjectUrl: typeof prepareImageDisplayObjectUrl;
8412
8492
  declare const media_service_prepareLocalMediaPreview: typeof prepareLocalMediaPreview;
8493
+ declare const media_service_prepareVideoPosterObjectUrl: typeof prepareVideoPosterObjectUrl;
8413
8494
  declare const media_service_prioritizeMediaDownload: typeof prioritizeMediaDownload;
8495
+ declare const media_service_resolveImageDisplayMaxSize: typeof resolveImageDisplayMaxSize;
8414
8496
  declare namespace media_service {
8415
8497
  export {
8416
8498
  media_service_acquireMediaBlob as acquireMediaBlob,
8417
8499
  media_service_detectImageMime as detectImageMime,
8418
8500
  media_service_detectVideoMime as detectVideoMime,
8501
+ media_service_loadCachedImageDisplayObjectUrl as loadCachedImageDisplayObjectUrl,
8419
8502
  media_service_loadCachedImageObjectUrl as loadCachedImageObjectUrl,
8420
8503
  media_service_loadCachedMediaAlbumItemObjectUrl as loadCachedMediaAlbumItemObjectUrl,
8421
8504
  media_service_loadCachedVideoObjectUrl as loadCachedVideoObjectUrl,
8505
+ media_service_loadCachedVideoPosterObjectUrl as loadCachedVideoPosterObjectUrl,
8422
8506
  media_service_loadFileObjectUrl as loadFileObjectUrl,
8507
+ media_service_loadImageDisplayObjectUrl as loadImageDisplayObjectUrl,
8423
8508
  media_service_loadImageObjectUrl as loadImageObjectUrl,
8424
8509
  media_service_loadMediaAlbumItemObjectUrl as loadMediaAlbumItemObjectUrl,
8425
8510
  media_service_loadVideoObjectUrl as loadVideoObjectUrl,
8426
8511
  media_service_loadVoiceBytes as loadVoiceBytes,
8512
+ media_service_prepareImageDisplayObjectUrl as prepareImageDisplayObjectUrl,
8427
8513
  media_service_prepareLocalMediaPreview as prepareLocalMediaPreview,
8514
+ media_service_prepareVideoPosterObjectUrl as prepareVideoPosterObjectUrl,
8428
8515
  media_service_prioritizeMediaDownload as prioritizeMediaDownload,
8516
+ media_service_resolveImageDisplayMaxSize as resolveImageDisplayMaxSize,
8429
8517
  };
8430
8518
  }
8431
8519
 
@@ -9642,6 +9730,8 @@ declare function resolveMediaTransferPresentation(input: {
9642
9730
  aggregateFrom?: number;
9643
9731
  /** 宿主确实持有的完整本地资源;单条媒体以 undefined 表示,缩略图不属于完整资源。 */
9644
9732
  availableItemIndices?: readonly (number | undefined)[];
9733
+ /** 仅气泡传入:已有清晰显示图或完整本机资源的项不显示下载胶囊;不能用作预览可用性证据。 */
9734
+ displayAvailableItemIndices?: readonly (number | undefined)[];
9645
9735
  /** SDK 明确查到完整缓存已不存在;历史 completed 任务不能替代当前资源证据。 */
9646
9736
  unavailableItemIndices?: readonly (number | undefined)[];
9647
9737
  /** 当前窗口正在查询的媒体项,不表示未下载。 */