@cut-workbench/core 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/chunks/{canvas-size-iWL8zZPl.js → canvas-size-CM2oKApi.js} +3 -144
  2. package/dist/chunks/{canvas-size-iWL8zZPl.js.map → canvas-size-CM2oKApi.js.map} +1 -1
  3. package/dist/chunks/{canvas-size-IzoEg2cq.cjs → canvas-size-Ct61OYjW.cjs} +26 -287
  4. package/dist/chunks/canvas-size-Ct61OYjW.cjs.map +1 -0
  5. package/dist/chunks/import-pipeline-A8KkqtZT.cjs +610 -0
  6. package/dist/chunks/import-pipeline-A8KkqtZT.cjs.map +1 -0
  7. package/dist/chunks/import-pipeline-DLIdgrIb.js +521 -0
  8. package/dist/chunks/import-pipeline-DLIdgrIb.js.map +1 -0
  9. package/dist/chunks/rolldown-runtime-B2SfzNBj.cjs +17 -0
  10. package/dist/chunks/rolldown-runtime-D8jQpDG7.js +12 -0
  11. package/dist/chunks/{snap-Dc022smD.js → snap-CBV9G4xq.js} +2 -2
  12. package/dist/chunks/{snap-Dc022smD.js.map → snap-CBV9G4xq.js.map} +1 -1
  13. package/dist/chunks/{snap-CeYuTN6d.cjs → snap-DyIuO2hU.cjs} +3 -3
  14. package/dist/chunks/{snap-CeYuTN6d.cjs.map → snap-DyIuO2hU.cjs.map} +1 -1
  15. package/dist/chunks/srt-D539yJ-n.js +51 -0
  16. package/dist/chunks/srt-D539yJ-n.js.map +1 -0
  17. package/dist/chunks/srt-DaL36mXN.cjs +73 -0
  18. package/dist/chunks/srt-DaL36mXN.cjs.map +1 -0
  19. package/dist/chunks/time-C_gvkVl1.js +145 -0
  20. package/dist/chunks/time-C_gvkVl1.js.map +1 -0
  21. package/dist/chunks/time-CnMfSVYX.cjs +264 -0
  22. package/dist/chunks/time-CnMfSVYX.cjs.map +1 -0
  23. package/dist/chunks/{waveform-CWU8Fa-n.js → waveform-DJkRtMct.js} +82 -12
  24. package/dist/chunks/waveform-DJkRtMct.js.map +1 -0
  25. package/dist/chunks/{waveform-Bhvv2t7-.cjs → waveform-Ie-G5Lle.cjs} +121 -21
  26. package/dist/chunks/waveform-Ie-G5Lle.cjs.map +1 -0
  27. package/dist/editor/create-editor.d.ts +8 -106
  28. package/dist/editor/editor-store.d.ts +4 -0
  29. package/dist/editor/handle-types.d.ts +256 -0
  30. package/dist/engine/index.cjs +961 -823
  31. package/dist/engine/index.cjs.map +1 -1
  32. package/dist/engine/index.d.ts +3 -0
  33. package/dist/engine/index.js +935 -803
  34. package/dist/engine/index.js.map +1 -1
  35. package/dist/engine/webav/export-runner.d.ts +61 -0
  36. package/dist/engine/webav/import-files.d.ts +43 -0
  37. package/dist/engine/webav/import-pipeline.d.ts +13 -1
  38. package/dist/errors.d.ts +12 -0
  39. package/dist/export/types.d.ts +49 -0
  40. package/dist/index.cjs +75 -65
  41. package/dist/index.cjs.map +1 -1
  42. package/dist/index.d.ts +5 -0
  43. package/dist/index.js +46 -43
  44. package/dist/index.js.map +1 -1
  45. package/dist/ports/host-bridge.d.ts +7 -0
  46. package/dist/project/file-storage.d.ts +23 -0
  47. package/dist/timeline/index.cjs +17 -16
  48. package/dist/timeline/index.js +3 -2
  49. package/package.json +78 -77
  50. package/dist/chunks/canvas-size-IzoEg2cq.cjs.map +0 -1
  51. package/dist/chunks/waveform-Bhvv2t7-.cjs.map +0 -1
  52. package/dist/chunks/waveform-CWU8Fa-n.js.map +0 -1
@@ -0,0 +1,256 @@
1
+ /**
2
+ * 编辑器句柄的公开契约(纯类型)。
3
+ *
4
+ * 本文件只含 `import type`,因此可以被根入口安全导出:不会把 WebAV /
5
+ * 运行时拉进 `@cut-workbench/core` 的模块图,Node 环境 import 依旧无副作用。
6
+ */
7
+ import type { StoreApi } from 'zustand/vanilla';
8
+ import type { MediaAsset, Project, SubtitleStyle, TextStyle, TimelineClip, Track } from '../types';
9
+ import type { SerializedProject } from '../project/schema';
10
+ import type { StoragePort } from '../project/storage';
11
+ import type { HostBridge, SaveFileResult } from '../ports/host-bridge';
12
+ import type { CapabilityReport } from '../capability';
13
+ import type { ExportHandle, ExportRequest, ExportResult } from '../export/types';
14
+ import type { EditorState } from './editor-store';
15
+ import type { HistoryStore } from './history-store';
16
+ import type { EventEmitterView } from './event-bus';
17
+ import type { EditorRuntime } from './runtime';
18
+ /** 对外事件表。新增事件时必须同步更新此接口。 */
19
+ export interface CutEventMap {
20
+ ready: {
21
+ editorId: string;
22
+ };
23
+ 'project:changed': {
24
+ project: Project;
25
+ dirty: boolean;
26
+ };
27
+ 'assets:changed': {
28
+ assets: MediaAsset[];
29
+ };
30
+ 'selection:changed': {
31
+ clipIds: string[];
32
+ assetId: string | null;
33
+ };
34
+ 'playhead:changed': {
35
+ us: number;
36
+ playing: boolean;
37
+ };
38
+ 'history:changed': {
39
+ canUndo: boolean;
40
+ canRedo: boolean;
41
+ };
42
+ /** 工程结构变化(dirty 由 false → true 或反向) */
43
+ 'project:dirty': {
44
+ dirty: boolean;
45
+ };
46
+ /** 保存完成(成功或失败);`path` 是宿主存储给出的位置(若有) */
47
+ 'project:saved': {
48
+ path?: string;
49
+ ok: boolean;
50
+ error?: string;
51
+ };
52
+ /** 工程载入完成;`missing` 是缺少二进制源的素材数 */
53
+ 'project:loaded': {
54
+ project: Project;
55
+ assetCount: number;
56
+ missing: number;
57
+ };
58
+ 'export:start': {
59
+ totalUs: number;
60
+ settings: import('../types').ExportSettings;
61
+ };
62
+ /** 0~1 */
63
+ 'export:progress': {
64
+ progress: number;
65
+ };
66
+ /**
67
+ * 导出完成。
68
+ *
69
+ * `result` 是完整结果(宿主入库需要时长 / 尺寸 / 码率)。
70
+ * 顶层 `blob` / `filename` 是为兼容既有订阅方保留的**便捷副本**,会被新代码忽略。
71
+ */
72
+ 'export:done': {
73
+ result: ExportResult;
74
+ blob: Blob;
75
+ filename: string;
76
+ };
77
+ 'export:error': {
78
+ message: string;
79
+ error: unknown;
80
+ };
81
+ error: {
82
+ scope: string;
83
+ error: unknown;
84
+ };
85
+ dispose: Record<string, never>;
86
+ }
87
+ /** 自动保存:结构性变更后节流写入 */
88
+ export interface AutoSaveOptions {
89
+ storage: StoragePort;
90
+ namespace: string;
91
+ /** 节流窗口,默认 2000ms */
92
+ intervalMs?: number;
93
+ }
94
+ export interface EditorOptions {
95
+ /** 宿主桥;不传则使用浏览器内置实现 */
96
+ bridge?: HostBridge;
97
+ /** 工程持久化端口;不传则用内存实现(不落盘) */
98
+ storage?: StoragePort;
99
+ /** 持久化命名空间(多项目 / 多实例隔离) */
100
+ namespace?: string;
101
+ /** 直接给一个完整工程 */
102
+ project?: Project;
103
+ /**
104
+ * 覆盖空工程的默认 id。宿主可用自己的项目 id,实现「一个项目一个剪辑工程」。
105
+ *
106
+ * 传了 `project` 时本字段被忽略(以工程自身的 id 为准)。
107
+ */
108
+ projectId?: string;
109
+ /** 初始素材元数据 */
110
+ assets?: MediaAsset[];
111
+ /** 自动保存;不传则不自动落盘 */
112
+ autoSave?: AutoSaveOptions;
113
+ }
114
+ export interface AddFilesOptions {
115
+ /** 导入成功后选中第一个素材;默认 true。批量预导入传 false,避免抢焦点 */
116
+ select?: boolean;
117
+ /** 逐文件进度:index 为入参数组下标,progress 为 0~1 */
118
+ onProgress?: (index: number, progress: number) => void;
119
+ /**
120
+ * 由宿主指定素材 id。返回 falsy 则回退到库生成的 `asset_xxx`。
121
+ * 用于宿主把自己的素材记录 id 作为 MediaAsset.id,实现「工程 ↔ 宿主库」一一对应。
122
+ */
123
+ idFor?: (file: File, index: number) => string | null | undefined;
124
+ /** 与缺失源文件的素材同名同类型时重连而非新增;默认 true */
125
+ reconnect?: boolean;
126
+ }
127
+ export interface AddFilesResult {
128
+ imported: MediaAsset[];
129
+ failures: Array<{
130
+ name: string;
131
+ error: string;
132
+ }>;
133
+ /** 其中走重连的数量 */
134
+ reconnected: number;
135
+ }
136
+ export interface AddTextAssetParams {
137
+ text: string;
138
+ style?: Partial<TextStyle>;
139
+ /** 素材默认时长(微秒);缺省 5s */
140
+ durationUs?: number;
141
+ }
142
+ export interface AddSubtitleAssetParams {
143
+ srt: string;
144
+ style?: Partial<SubtitleStyle>;
145
+ /** 素材默认时长(微秒);缺省取 SRT 最后一条字幕的结束时间 */
146
+ durationUs?: number;
147
+ }
148
+ export interface ImportJsonOptions {
149
+ /**
150
+ * 由宿主补齐二进制。返回 null 表示该素材缺失,进入 missingAssetIds。
151
+ */
152
+ resolveFile?: (asset: MediaAsset) => Promise<File | null>;
153
+ }
154
+ export interface ImportJsonResult {
155
+ missingAssetIds: string[];
156
+ }
157
+ export interface SaveAsResult {
158
+ ok: boolean;
159
+ path?: string;
160
+ error?: string;
161
+ }
162
+ /**
163
+ * 时间轴命令门面。
164
+ *
165
+ * 与 `CutEditorHandle` 上的同名方法完全等价,供宿主在「注入命令对象」的
166
+ * 场景(例如自己的快捷键表)里使用。
167
+ */
168
+ export interface EditorCommands {
169
+ updateClip: (clipId: string, patch: Partial<TimelineClip>, recordHistory?: boolean, mergeKey?: string) => void;
170
+ moveClip: (clipId: string, trackId: string, startUs: number, recordHistory?: boolean) => void;
171
+ trimClip: (clipId: string, edge: 'start' | 'end', deltaUs: number, recordHistory?: boolean) => void;
172
+ splitClipsAt: (atUs: number, clipIds?: string[]) => string[];
173
+ duplicateSelection: (offsetUs: number) => Array<{
174
+ sourceId: string;
175
+ newId: string;
176
+ }>;
177
+ addTrack: (kind: Track['kind']) => string;
178
+ removeTrack: (trackId: string) => void;
179
+ updateTrack: (trackId: string, patch: Partial<Track>) => void;
180
+ }
181
+ export interface CutEditorHandle {
182
+ readonly id: string;
183
+ readonly store: StoreApi<EditorState>;
184
+ readonly history: HistoryStore;
185
+ readonly runtime: EditorRuntime;
186
+ readonly events: EventEmitterView<CutEventMap>;
187
+ readonly bridge: HostBridge;
188
+ readonly storage: StoragePort;
189
+ /** 时间轴命令门面(与下方同名方法等价) */
190
+ readonly commands: EditorCommands;
191
+ getProject(): Project;
192
+ getProjectId(): string;
193
+ /** 运行期改 id;会同步 emit `project:changed` */
194
+ setProjectId(id: string): void;
195
+ renameProject(name: string): void;
196
+ setProjectSize(width: number, height: number, mode?: 'scale' | 'keep'): void;
197
+ getAssets(): MediaAsset[];
198
+ getState(): EditorState;
199
+ setProject(project: Project, assets: MediaAsset[], missingAssetIds?: string[]): void;
200
+ serialize(): SerializedProject;
201
+ /** `serialize()` 的别名,语义更直白 */
202
+ exportJson(): SerializedProject;
203
+ /** 从 JSON / Project 恢复(不补齐二进制,缺源素材进入 missingAssetIds) */
204
+ load(input: SerializedProject | Project): Promise<void>;
205
+ /**
206
+ * 从 JSON 恢复,并由宿主补齐二进制。
207
+ * `resolveFile(asset)` 返回 null 表示该素材缺失,进入 missingAssetIds。
208
+ */
209
+ importJson(data: SerializedProject, options?: ImportJsonOptions): Promise<ImportJsonResult>;
210
+ save(): Promise<SaveAsResult>;
211
+ /** 换一个存储端口 / 命名空间保存,并把它设为后续 `save()` 的目标 */
212
+ saveAs(storage: StoragePort, namespace: string): Promise<SaveAsResult>;
213
+ isDirty(): boolean;
214
+ isEmpty(): boolean;
215
+ addFiles(files: File[], options?: AddFilesOptions): Promise<AddFilesResult>;
216
+ addTextAsset(params: AddTextAssetParams): Promise<MediaAsset>;
217
+ addSubtitleAsset(params: AddSubtitleAssetParams): Promise<MediaAsset>;
218
+ /** 为缺失源文件的素材补上文件(重新打开工程、按 id 找回本地文件后调用) */
219
+ reconnectAsset(assetId: string, file: File): Promise<void>;
220
+ getMissingAssetIds(): string[];
221
+ removeAsset(assetId: string): void;
222
+ play(): void;
223
+ pause(): void;
224
+ toggle(): void;
225
+ seek(us: number): void;
226
+ getPlayhead(): number;
227
+ getDuration(): number;
228
+ isPlaying(): boolean;
229
+ undo(): void;
230
+ redo(): void;
231
+ canUndo(): boolean;
232
+ canRedo(): boolean;
233
+ addClip(clip: TimelineClip): void;
234
+ removeClips(ids: string[]): void;
235
+ selectClips(ids: string[]): void;
236
+ getSelectedClipIds(): string[];
237
+ setSelection(clipIds: string[], assetId?: string | null): void;
238
+ updateClip(clipId: string, patch: Partial<TimelineClip>, recordHistory?: boolean, mergeKey?: string): void;
239
+ moveClip(clipId: string, trackId: string, startUs: number, recordHistory?: boolean): void;
240
+ trimClip(clipId: string, edge: 'start' | 'end', deltaUs: number, recordHistory?: boolean): void;
241
+ splitClipsAt(atUs: number, clipIds?: string[]): string[];
242
+ duplicateSelection(offsetUs: number): Array<{
243
+ sourceId: string;
244
+ newId: string;
245
+ }>;
246
+ addTrack(kind: Track['kind']): string;
247
+ removeTrack(trackId: string): void;
248
+ updateTrack(trackId: string, patch: Partial<Track>): void;
249
+ /** 启动导出;内部优先 Worker,不可用时回退主线程 */
250
+ export(request?: ExportRequest): ExportHandle;
251
+ /** 把导出结果交给宿主落盘(`bridge.files.saveBlob`) */
252
+ saveExport(result: ExportResult, suggestedName?: string): Promise<SaveFileResult>;
253
+ /** 能力探测结果(首次调用后缓存) */
254
+ getCapabilities(): Promise<CapabilityReport>;
255
+ dispose(): Promise<void>;
256
+ }