@video-editor/editor-core 0.0.1-beta.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.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # @video-editor/editor-core
2
+
3
+ Headless editor core built on the reactive video protocol. It exposes state, commands, selectors, and a plugin registry without any UI dependencies.
@@ -0,0 +1,251 @@
1
+ import { ComputedRef } from '@vue/reactivity';
2
+ import { createVideoProtocolManager } from '@video-editor/protocol';
3
+ import { DeepReadonly } from '@vue/reactivity';
4
+ import { ITrackType } from '@video-editor/shared';
5
+ import { IVideoProtocol } from '@video-editor/shared';
6
+ import { SegmentUnion } from '@video-editor/shared';
7
+ import { TrackUnion } from '@video-editor/shared';
8
+
9
+ /** Result payload returned by addSegment. */
10
+ export declare type AddSegmentResult = ReturnType<ProtocolManager['addSegment']>;
11
+
12
+ export declare function createEditorCore(options: EditorCoreOptions): EditorCore;
13
+
14
+ export declare function createPluginManager(ctx: EditorCoreContext): EditorCorePluginManager;
15
+
16
+ export declare function createSegmentRegistry(): SegmentRegistry;
17
+
18
+ /**
19
+ * The headless editor-core instance.
20
+ */
21
+ export declare interface EditorCore {
22
+ /** Read-only state tree. */
23
+ state: EditorCoreState;
24
+ /** Mutation commands. */
25
+ commands: EditorCoreCommands;
26
+ /** Read-only selectors. */
27
+ selectors: EditorCoreSelectors;
28
+ /** Plugin manager instance. */
29
+ plugins: EditorCorePluginManager;
30
+ /** Segment plugin registry. */
31
+ registry: {
32
+ segments: SegmentRegistry;
33
+ };
34
+ /** Shared services passed at initialization. */
35
+ services: EditorCoreServices;
36
+ /** Dispose resources. */
37
+ destroy: () => Promise<void>;
38
+ }
39
+
40
+ /**
41
+ * Commands are the only supported way to mutate protocol state.
42
+ */
43
+ export declare interface EditorCoreCommands {
44
+ /** Set the playhead time in ms. */
45
+ setCurrentTime: (time: number) => void;
46
+ /** Update the selected segment id. */
47
+ setSelectedSegment: ProtocolManager['setSelectedSegment'];
48
+ /** Insert a segment into the timeline. */
49
+ addSegment: ProtocolManager['addSegment'];
50
+ /** Remove a segment by id. */
51
+ removeSegment: ProtocolManager['removeSegment'];
52
+ /** Mutate a segment (by id or current selection). */
53
+ updateSegment: ProtocolManager['updateSegment'];
54
+ /** Move a segment between tracks or positions. */
55
+ moveSegment: ProtocolManager['moveSegment'];
56
+ /** Resize a segment's time range. */
57
+ resizeSegment: ProtocolManager['resizeSegment'];
58
+ /** Add a transition at the current time or a specified time. */
59
+ addTransition: ProtocolManager['addTransition'];
60
+ /** Remove a transition by segment id. */
61
+ removeTransition: ProtocolManager['removeTransition'];
62
+ /** Update a transition by segment id. */
63
+ updateTransition: ProtocolManager['updateTransition'];
64
+ /** Replace a track id (useful for migrations). */
65
+ replaceTrackId: ProtocolManager['replaceTrackId'];
66
+ /** Undo the last mutation. */
67
+ undo: ProtocolManager['undo'];
68
+ /** Redo the last undone mutation. */
69
+ redo: ProtocolManager['redo'];
70
+ /** Export the current protocol as a plain object snapshot. */
71
+ exportProtocol: ProtocolManager['exportProtocol'];
72
+ }
73
+
74
+ /**
75
+ * The context passed to plugin creators.
76
+ */
77
+ export declare interface EditorCoreContext {
78
+ state: EditorCoreState;
79
+ commands: EditorCoreCommands;
80
+ selectors: EditorCoreSelectors;
81
+ registry: {
82
+ segments: SegmentRegistry;
83
+ };
84
+ services: EditorCoreServices;
85
+ }
86
+
87
+ /**
88
+ * Editor-core initialization options.
89
+ */
90
+ export declare interface EditorCoreOptions {
91
+ /** Initial protocol snapshot. */
92
+ protocol: IVideoProtocol;
93
+ /** Optional id generators for segments/tracks. */
94
+ idFactory?: {
95
+ segment?: () => string;
96
+ track?: () => string;
97
+ };
98
+ /** Optional shared services (resource manager, renderer, etc). */
99
+ services?: EditorCoreServices;
100
+ }
101
+
102
+ /**
103
+ * Base plugin interface for editor-core.
104
+ */
105
+ export declare interface EditorCorePlugin {
106
+ /** Plugin name, must be unique within the editor instance. */
107
+ name: string;
108
+ /** Initialize side effects or register UI/handlers. */
109
+ init?: () => Promise<void> | void;
110
+ /** Cleanup side effects. */
111
+ destroy?: () => Promise<void> | void;
112
+ /** Optional plugin metadata. */
113
+ meta?: {
114
+ dependencies?: string[];
115
+ };
116
+ }
117
+
118
+ /** Create a plugin from the editor context. */
119
+ export declare type EditorCorePluginCreator = (ctx: EditorCoreContext) => EditorCorePlugin;
120
+
121
+ /**
122
+ * Plugin manager used by editor-core.
123
+ */
124
+ export declare interface EditorCorePluginManager {
125
+ /** Register a plugin creator. */
126
+ register: (pluginCreator: EditorCorePluginCreator, options?: {
127
+ autoInit?: boolean;
128
+ override?: boolean;
129
+ }) => Promise<void>;
130
+ /** Initialize all registered plugins. */
131
+ init: () => Promise<void>;
132
+ /** Fetch a plugin by name. */
133
+ get: (pluginName: string) => EditorCorePlugin | undefined;
134
+ /** Check if a plugin exists. */
135
+ has: (pluginName: string) => boolean;
136
+ /** Remove a plugin by name (calls destroy). */
137
+ remove: (pluginName: string) => Promise<boolean>;
138
+ /** Destroy and clear all plugins. */
139
+ destroy: () => Promise<void>;
140
+ }
141
+
142
+ /**
143
+ * Read-only helpers for querying protocol data.
144
+ */
145
+ export declare interface EditorCoreSelectors {
146
+ /** Find a segment by id (and optionally type). */
147
+ getSegment: ProtocolManager['getSegment'];
148
+ /** Find a track by id (read-only reference). */
149
+ getTrackById: (trackId: string) => DeepReadonly<TrackUnion> | undefined;
150
+ /** Find the track that owns a segment id. */
151
+ getTrackBySegmentId: (segmentId: string) => DeepReadonly<TrackUnion> | undefined;
152
+ /** List tracks, optionally filtered by type. */
153
+ getTracks: (trackType?: ITrackType) => DeepReadonly<TrackUnion>[];
154
+ }
155
+
156
+ /**
157
+ * Arbitrary shared services injected into editor-core (resource, renderer, etc).
158
+ */
159
+ export declare interface EditorCoreServices {
160
+ [key: string]: unknown;
161
+ }
162
+
163
+ /**
164
+ * Read-only editor state derived from the reactive protocol.
165
+ * All mutations should go through commands.
166
+ */
167
+ export declare interface EditorCoreState {
168
+ /** Reactive protocol snapshot. */
169
+ protocol: ProtocolManager['protocol'];
170
+ /** Project-level properties (width/height/fps/version). */
171
+ videoBasicInfo: ProtocolManager['videoBasicInfo'];
172
+ /** Current playhead time in ms. */
173
+ currentTime: ProtocolManager['curTime'];
174
+ /** Currently selected segment (read-only). */
175
+ selectedSegment: ProtocolManager['selectedSegment'];
176
+ /** Selected segment id, derived from the current selection. */
177
+ selectedSegmentId: ComputedRef<string | undefined>;
178
+ /** Track list grouped by segment type. */
179
+ trackMap: ProtocolManager['trackMap'];
180
+ /** Segment lookup table keyed by segment id. */
181
+ segmentMap: ProtocolManager['segmentMap'];
182
+ /** Total duration computed from protocol tracks. */
183
+ duration: ComputedRef<number>;
184
+ /** Undo stack size. */
185
+ undoCount: ProtocolManager['undoCount'];
186
+ /** Redo stack size. */
187
+ redoCount: ProtocolManager['redoCount'];
188
+ }
189
+
190
+ /** Options for moving a segment between tracks or within a track. */
191
+ export declare type MoveSegmentOptions = Parameters<ProtocolManager['moveSegment']>[0];
192
+
193
+ /** Internal protocol manager type used to align editor-core signatures with protocol behavior. */
194
+ declare type ProtocolManager = ReturnType<typeof createVideoProtocolManager>;
195
+
196
+ /** Options for resizing a segment on a track. */
197
+ export declare type ResizeSegmentOptions = Parameters<ProtocolManager['resizeSegment']>[0];
198
+
199
+ /** Input payload for adding a segment (id is optional). */
200
+ export declare type SegmentInput = Parameters<ProtocolManager['addSegment']>[0];
201
+
202
+ /** Result payload returned by segment mutation commands. */
203
+ export declare type SegmentMutationResult = ReturnType<ProtocolManager['removeSegment']>;
204
+
205
+ /**
206
+ * Segment plugin bundle: ops + renderer adapter + optional UI bindings.
207
+ */
208
+ export declare interface SegmentPlugin<TSegment extends SegmentUnion = SegmentUnion, RenderNode = unknown, UI = SegmentPluginUI> {
209
+ /** The segment type this plugin handles. */
210
+ type: TSegment['segmentType'];
211
+ /** Optional operations for this segment type. */
212
+ ops?: SegmentPluginOps<TSegment>;
213
+ /** Convert a segment into a renderer-specific node. */
214
+ renderer?: {
215
+ toRenderNode: (segment: TSegment, ctx: EditorCoreContext) => RenderNode | null;
216
+ };
217
+ /** Optional UI bindings (panel, track, resource). */
218
+ ui?: UI;
219
+ }
220
+
221
+ /**
222
+ * Optional behavior hooks for a segment type.
223
+ */
224
+ export declare interface SegmentPluginOps<TSegment extends SegmentUnion = SegmentUnion> {
225
+ create?: (ctx: EditorCoreContext, partial?: Partial<TSegment>) => TSegment;
226
+ update?: (ctx: EditorCoreContext, id: string, patch: Partial<TSegment>) => void;
227
+ remove?: (ctx: EditorCoreContext, id: string) => void;
228
+ split?: (ctx: EditorCoreContext, id: string, time: number) => void;
229
+ }
230
+
231
+ /**
232
+ * Optional UI bindings for a segment plugin (editor-ui can consume these).
233
+ */
234
+ export declare interface SegmentPluginUI {
235
+ panel?: unknown;
236
+ track?: unknown;
237
+ resource?: unknown;
238
+ }
239
+
240
+ /**
241
+ * Registry for segment-type plugins (type -> plugin lookup).
242
+ */
243
+ export declare interface SegmentRegistry {
244
+ register: (plugin: SegmentPlugin, options?: {
245
+ override?: boolean;
246
+ }) => void;
247
+ get: (type: ITrackType) => SegmentPlugin | undefined;
248
+ list: () => SegmentPlugin[];
249
+ }
250
+
251
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,116 @@
1
+ import { computed as p } from "@vue/reactivity";
2
+ import { createVideoProtocolManager as v } from "@video-editor/protocol";
3
+ function y(s) {
4
+ const e = [], r = /* @__PURE__ */ new Map();
5
+ let a = !1;
6
+ return {
7
+ register: async (t, n) => {
8
+ const i = t(s), { name: c } = i;
9
+ if (r.has(c)) {
10
+ if (!n?.override)
11
+ throw new Error(`Plugin ${c} has been registered`);
12
+ await r.get(c)?.destroy?.();
13
+ const u = e.findIndex((S) => S.name === c);
14
+ u >= 0 && e.splice(u, 1), r.delete(c);
15
+ }
16
+ e.push(i), r.set(c, i), (n?.autoInit || a) && await i.init?.();
17
+ },
18
+ init: async () => {
19
+ for (const t of e)
20
+ await t.init?.();
21
+ a = !0;
22
+ },
23
+ get: (t) => r.get(t),
24
+ has: (t) => r.has(t),
25
+ remove: async (t) => {
26
+ const n = e.findIndex((c) => c.name === t);
27
+ return n === -1 ? !1 : (await e[n].destroy?.(), e.splice(n, 1), r.delete(t));
28
+ },
29
+ destroy: async () => {
30
+ for (const t of e)
31
+ await t.destroy?.();
32
+ e.length = 0, r.clear(), a = !1;
33
+ }
34
+ };
35
+ }
36
+ function T() {
37
+ const s = /* @__PURE__ */ new Map();
38
+ return {
39
+ register: (o, d) => {
40
+ if (s.has(o.type) && !d?.override)
41
+ throw new Error(`Segment plugin ${o.type} has been registered`);
42
+ s.set(o.type, o);
43
+ },
44
+ get: (o) => s.get(o),
45
+ list: () => [...s.values()]
46
+ };
47
+ }
48
+ function k(s) {
49
+ let e = 0;
50
+ for (const r of s)
51
+ for (const a of r.children)
52
+ a.endTime > e && (e = a.endTime);
53
+ return e;
54
+ }
55
+ function I(s) {
56
+ const e = v(s.protocol, {
57
+ idFactory: s.idFactory
58
+ }), r = p(() => e.selectedSegment.value?.id), a = p(() => k(e.protocol.value.tracks)), o = {
59
+ protocol: e.protocol,
60
+ videoBasicInfo: e.videoBasicInfo,
61
+ currentTime: e.curTime,
62
+ selectedSegment: e.selectedSegment,
63
+ selectedSegmentId: r,
64
+ trackMap: e.trackMap,
65
+ segmentMap: e.segmentMap,
66
+ duration: a,
67
+ undoCount: e.undoCount,
68
+ redoCount: e.redoCount
69
+ }, d = {
70
+ setCurrentTime: (n) => {
71
+ e.curTime.value = n;
72
+ },
73
+ setSelectedSegment: e.setSelectedSegment,
74
+ addSegment: e.addSegment,
75
+ removeSegment: e.removeSegment,
76
+ updateSegment: e.updateSegment,
77
+ moveSegment: e.moveSegment,
78
+ resizeSegment: e.resizeSegment,
79
+ addTransition: e.addTransition,
80
+ removeTransition: e.removeTransition,
81
+ updateTransition: e.updateTransition,
82
+ replaceTrackId: e.replaceTrackId,
83
+ undo: e.undo,
84
+ redo: e.redo,
85
+ exportProtocol: e.exportProtocol
86
+ }, g = {
87
+ getSegment: e.getSegment,
88
+ getTrackById: (n) => o.protocol.value.tracks.find((i) => i.trackId === n),
89
+ getTrackBySegmentId: (n) => o.protocol.value.tracks.find((i) => i.children.some((c) => c.id === n)),
90
+ getTracks: (n) => n ? o.protocol.value.tracks.filter((i) => i.trackType === n) : o.protocol.value.tracks
91
+ }, l = {
92
+ segments: T()
93
+ }, m = s.services ?? {}, t = y({
94
+ state: o,
95
+ commands: d,
96
+ selectors: g,
97
+ registry: l,
98
+ services: m
99
+ });
100
+ return {
101
+ state: o,
102
+ commands: d,
103
+ selectors: g,
104
+ plugins: t,
105
+ registry: l,
106
+ services: m,
107
+ destroy: async () => {
108
+ await t.destroy();
109
+ }
110
+ };
111
+ }
112
+ export {
113
+ I as createEditorCore,
114
+ y as createPluginManager,
115
+ T as createSegmentRegistry
116
+ };
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@video-editor/editor-core",
3
+ "type": "module",
4
+ "version": "0.0.1-beta.17",
5
+ "exports": {
6
+ ".": {
7
+ "import": "./dist/index.js"
8
+ },
9
+ "./*": "./*"
10
+ },
11
+ "main": "dist/index.js",
12
+ "module": "dist/index.js",
13
+ "types": "dist/index.d.ts",
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "peerDependencies": {
18
+ "@vue/reactivity": "^3.5.26"
19
+ },
20
+ "dependencies": {
21
+ "@video-editor/protocol": "0.0.1-beta.17",
22
+ "@video-editor/shared": "0.0.1-beta.17"
23
+ },
24
+ "devDependencies": {
25
+ "@vue/reactivity": "^3.5.26"
26
+ },
27
+ "scripts": {
28
+ "build:types": "vue-tsc --declaration --emitDeclarationOnly",
29
+ "build": "vite build",
30
+ "preview": "vite preview"
31
+ }
32
+ }