@volcengine/amk-editor 0.0.2 → 0.0.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/README.md CHANGED
@@ -65,7 +65,7 @@ editor.destroy();
65
65
  - 产物是单文件 ESM。依赖里的 AMD `define(["./core"])` 已在构建时剔除,避免 Next.js / webpack 误解析不存在的 `dist/core.js`。
66
66
  - `getHeaders` 可选,每次请求前都会重新调用;SDK 不解析、不缓存、不改写返回值,仅将其合并到发往 `endpoint` 的工程、素材、tools、tasks、导出等请求中。闭包内 Token 更新会自动用于下一次请求。
67
67
  - 本地上传、URL 导入由业务回调完成。返回的素材必须带业务主键 `source_material_id`,不必填写 `material_id`。
68
- - 播放地址、封面、雪碧图可能有时效。通过 `onRefreshPlayInfo` 返回新的访问地址。
68
+ - 播放地址、封面、雪碧图可能有时效。通过 `onRefreshPlayInfo` 返回新的访问地址;补丁按 `material_id`、`source_material_id`、无标识时数组顺序依次匹配,未返回的字段保持原值。
69
69
  - 可选实现 `onMaterialsImported`:素材成功入库后回调已合并 `material_id` 的列表;可用于把新素材挂到对话草稿。失败或取消不会触发。
70
70
  - 可选实现 `onPersistExtractUrls`:把抽帧得到的临时地址转存为业务长期地址,并随 `materialPatch` 写回自定义存储字段。
71
71
  - 可选配置 `export.qualityEnhancement: true` 以在导出弹窗展示「视频画质增强」;默认不展示。
@@ -20,6 +20,8 @@ export declare class AmkEditor {
20
20
  private emptyTrackConfirmInFlight?;
21
21
  private readonly apiClient;
22
22
  private readonly ready;
23
+ private readonly bootstrapAbortController;
24
+ private destroyed;
23
25
  private projectName?;
24
26
  private editorRevision;
25
27
  private projectHydrated;
@@ -29,6 +31,11 @@ export declare class AmkEditor {
29
31
  private emptyTrackSaveBlocked;
30
32
  private savedMaterials;
31
33
  private saveQueue;
34
+ /** 最近一次 GET 或成功 PUT 后的服务端 editor 深比较基线。 */
35
+ private latestEditorFingerprint;
36
+ private latestEditorHasTrack;
37
+ /** 正在等待或执行的 editor 文档快照,用于合并高频重复事件。 */
38
+ private readonly pendingEditorSaveFingerprints;
32
39
  private projectRefreshInFlight?;
33
40
  private pendingSaveCount;
34
41
  private readonly asrPollingControllers;
@@ -65,6 +72,10 @@ export declare class AmkEditor {
65
72
  /** 所有 TOS 素材共用一个刷新定时器,避免按素材创建大量 timer。 */
66
73
  private tosSignedUrlRefreshTimer?;
67
74
  private tosSignedUrlRefreshInFlight?;
75
+ /** 同一轮播放地址刷新合并 materialId,并串行执行各批次,避免并发覆盖轨道和 revision。 */
76
+ private readonly pendingPlayInfoRefreshes;
77
+ private playInfoRefreshBatchScheduled;
78
+ private playInfoRefreshQueue;
68
79
  private readonly handleVisibilityChange;
69
80
  private readonly handleTrackChanged;
70
81
  private readonly handleEditParamChanged;
@@ -121,13 +132,19 @@ export declare class AmkEditor {
121
132
  * @param materialIdOrIds 单个 material_id、material_id 列表;省略则刷新当前全部有 material_id 的素材
122
133
  */
123
134
  refreshPlayInfo(materialIdOrIds?: string | string[]): Promise<MaterialItem | MaterialItem[] | undefined>;
135
+ private flushPlayInfoRefreshBatch;
124
136
  private refreshPlayInfoInternal;
137
+ /**
138
+ * 异步初始化入口:并行加载工程与预设,完成数据归一化后再挂载编辑器,
139
+ * 最后注册运行期的 URL 刷新和页面可见性监听。destroy() 可随时中断该流程。
140
+ */
125
141
  private bootstrap;
126
142
  /** 内置拉取工程:project + materials + editor → 归一化 → 组装 initialData。 */
127
143
  private resolveAndApplyProject;
128
144
  /**
129
145
  * 初始化时批量 refresh 素材(完整素材列表交给业务方),
130
- * 再把轨道元素里的 URL 回填到最新值,完成后回写 editor 文档。
146
+ * 再把轨道元素里的 URL 回填到当前运行时。仅 UserData 变化不回写 editor 文档;
147
+ * Source 等真实协议字段变化时才保存。
131
148
  */
132
149
  private refreshProjectOnInit;
133
150
  /** TOS 私有桶签名刷新优先,宿主刷新回调随后可继续覆盖播放信息。 */
@@ -146,6 +163,7 @@ export declare class AmkEditor {
146
163
  mount(): VeVeditorInstance | undefined;
147
164
  private mountVeVeditor;
148
165
  destroy(): void;
166
+ private assertNotDestroyed;
149
167
  private resolveConfig;
150
168
  /** 与 VeVeditor 同一套顶层扁平资源字段:boolean 面板开关 + 内部 xgplayer 组装 */
151
169
  private resolveVeVeditorOptions;
@@ -158,6 +176,7 @@ export declare class AmkEditor {
158
176
  */
159
177
  private deleteMaterial;
160
178
  private queueEditorSave;
179
+ private setLatestEditorSnapshot;
161
180
  private confirmAbnormalEmptyTrackSave;
162
181
  private enqueueEditorSaveWithCurrentEditParam;
163
182
  /**
@@ -10,4 +10,6 @@ export type PresetLibraryItem = {
10
10
  default?: boolean;
11
11
  };
12
12
  export type PresetLibrary = Partial<Record<PresetLibraryResourceKey, PresetLibraryItem[]>>;
13
- export declare function fetchPresetLibrary(client: Pick<AmkApiClient, 'requestJson'>, resources: PresetLibraryResourceKey[]): Promise<PresetLibrary>;
13
+ export declare function fetchPresetLibrary(client: Pick<AmkApiClient, 'requestJson'>, resources: PresetLibraryResourceKey[], options?: {
14
+ signal?: AbortSignal;
15
+ }): Promise<PresetLibrary>;
@@ -8,8 +8,12 @@ export type SavedAmkEditor = {
8
8
  revision: number;
9
9
  editParam: Record<string, unknown>;
10
10
  };
11
- export declare function fetchAmkProjectMaterials(client: EditingApiClient, projectId: string): Promise<MaterialItem[]>;
12
- export declare function fetchAmkProject(client: EditingApiClient, projectId: string): Promise<LoadedAmkProject>;
11
+ export declare function fetchAmkProjectMaterials(client: EditingApiClient, projectId: string, options?: {
12
+ signal?: AbortSignal;
13
+ }): Promise<MaterialItem[]>;
14
+ export declare function fetchAmkProject(client: EditingApiClient, projectId: string, options?: {
15
+ signal?: AbortSignal;
16
+ }): Promise<LoadedAmkProject>;
13
17
  export declare function updateAmkProjectName(client: EditingApiClient, projectId: string, projectName: string): Promise<void>;
14
18
  /**
15
19
  * POST 一批新素材到 AMK 工程。
@@ -1,12 +1,15 @@
1
1
  import { type TaskPollingController } from './task-polling';
2
2
  export declare const EXPORT_TASK_POLL_INTERVAL_MS = 5000;
3
+ export declare const EXPORT_TASK_VISIBLE_WINDOW_MS: number;
3
4
  export type ExportTaskPollingStatus = 'polling' | 'success' | 'failed';
4
5
  export declare function resolveExportTaskPollingStatus(payload: unknown): ExportTaskPollingStatus;
5
6
  export declare function resolveExportTaskProgress(payload: unknown): number | undefined;
6
7
  export declare function resolveExportTaskOutputUrl(payload: unknown): string | undefined;
8
+ /** 服务端仍查最新 10 条,前端只展示提交时间位于最近 24 小时内的任务。 */
9
+ export declare function filterRecentExportTasks<T extends Record<string, unknown>>(items: T[], now?: number): T[];
7
10
  export declare function startExportTaskPolling(options: {
8
11
  taskId: string;
9
12
  getTask: (taskId: string) => Promise<unknown>;
10
13
  onStatusChange: (status: ExportTaskPollingStatus, payload?: unknown) => void | Promise<void>;
11
- onError?: (error: unknown) => void;
14
+ onError?: (error: unknown) => void | Promise<void>;
12
15
  }): TaskPollingController;
package/dist/header.d.ts CHANGED
@@ -30,6 +30,8 @@ export type AmkExportTaskListItem = {
30
30
  name: string;
31
31
  format: 'mp4' | 'mp3';
32
32
  status: Exclude<AmkExportTaskStatus, 'idle'>;
33
+ /** 任务提交时间;历史任务来自任务列表接口的 submitted_at。 */
34
+ submittedAt?: string;
33
35
  /** 服务端返回的任务进度(0-100);没有进度时使用不定长动画。 */
34
36
  progress?: number;
35
37
  /** 是否已在当前页面触发过浏览器下载。 */