@twick/timeline 0.14.2 → 0.14.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 +86 -0
- package/dist/context/timeline-context.d.ts +103 -0
- package/dist/core/track/track.d.ts +323 -18
- package/dist/core/visitor/element-adder.d.ts +122 -2
- package/dist/index.js +441 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +441 -18
- package/dist/index.mjs.map +1 -1
- package/dist/utils/constants.d.ts +172 -35
- package/dist/utils/timeline.utils.d.ts +112 -0
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @twick/timeline
|
|
2
2
|
|
|
3
|
+
Timeline management and editing capabilities for video projects.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides a comprehensive timeline editor with CRUD operations for managing video tracks and elements. It uses the visitor pattern to handle different element types consistently and offers a fluent interface for timeline manipulation.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @twick/timeline
|
|
13
|
+
# or
|
|
14
|
+
pnpm add @twick/timeline
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { TimelineEditor, TimelineOperationContext } from '@twick/timeline';
|
|
21
|
+
|
|
22
|
+
// Create editor with context
|
|
23
|
+
const context: TimelineOperationContext = {
|
|
24
|
+
contextId: 'my-editor',
|
|
25
|
+
setTotalDuration: (duration) => console.log('Duration:', duration),
|
|
26
|
+
setPresent: (data) => console.log('Present:', data),
|
|
27
|
+
handleUndo: () => console.log('Undo'),
|
|
28
|
+
handleRedo: () => console.log('Redo'),
|
|
29
|
+
handleResetHistory: () => console.log('Reset History'),
|
|
30
|
+
setLatestProjectVersion: (version) => console.log('Version:', version),
|
|
31
|
+
setTimelineAction: (action, payload) => console.log('Action:', action, payload),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const editor = new TimelineEditor(context);
|
|
35
|
+
const track = editor.addTrack('My Video Track');
|
|
36
|
+
```
|
|
37
|
+
|
|
3
38
|
## Timeline Editor CRUD Operations
|
|
4
39
|
|
|
5
40
|
The TimelineEditor provides a clean interface for managing tracks and elements using the visitor pattern.
|
|
@@ -172,4 +207,55 @@ function MyComponent() {
|
|
|
172
207
|
}
|
|
173
208
|
```
|
|
174
209
|
|
|
210
|
+
## API Reference
|
|
211
|
+
|
|
212
|
+
### Core Classes
|
|
213
|
+
|
|
214
|
+
- `TimelineEditor`: Main timeline editor class
|
|
215
|
+
- `TextElement`: Text element implementation
|
|
216
|
+
- `VideoElement`: Video element implementation
|
|
217
|
+
- `ImageElement`: Image element implementation
|
|
218
|
+
- `AudioElement`: Audio element implementation
|
|
219
|
+
|
|
220
|
+
### Hooks
|
|
221
|
+
|
|
222
|
+
- `useTimelineContext`: React hook for timeline context
|
|
223
|
+
|
|
224
|
+
### Utility Functions
|
|
225
|
+
|
|
226
|
+
- `getCurrentElements`: Get elements at specific time
|
|
227
|
+
- `getTotalDuration`: Calculate total timeline duration
|
|
228
|
+
- `generateShortUuid`: Generate unique IDs
|
|
229
|
+
- `isElementId`: Check if ID is element type
|
|
230
|
+
- `isTrackId`: Check if ID is track type
|
|
231
|
+
|
|
232
|
+
### Types
|
|
233
|
+
|
|
234
|
+
- `TimelineOperationContext`: Context interface for timeline operations
|
|
235
|
+
- `TrackElement`: Base track element interface
|
|
236
|
+
|
|
237
|
+
For complete API documentation, refer to the generated documentation.
|
|
238
|
+
|
|
239
|
+
## Browser Support
|
|
240
|
+
|
|
241
|
+
This package requires a browser environment with support for:
|
|
242
|
+
- Modern JavaScript features (ES2020+)
|
|
243
|
+
- Promise and async/await support
|
|
244
|
+
|
|
245
|
+
## Documentation
|
|
246
|
+
|
|
247
|
+
For complete documentation, refer to the project documentation site.
|
|
248
|
+
|
|
249
|
+
## License
|
|
250
|
+
|
|
251
|
+
This package is licensed under the **Sustainable Use License (SUL) Version 1.0**.
|
|
252
|
+
|
|
253
|
+
- Free for use in commercial and non-commercial apps
|
|
254
|
+
- Can be modified and self-hosted
|
|
255
|
+
- Cannot be sold, rebranded, or distributed as a standalone SDK
|
|
256
|
+
|
|
257
|
+
For commercial licensing inquiries, contact: contact@kifferai.com
|
|
258
|
+
|
|
259
|
+
For full license terms, see the main LICENSE.md file in the project root.
|
|
260
|
+
|
|
175
261
|
|
|
@@ -3,31 +3,134 @@ import { TrackElement } from '../core/elements/base.element';
|
|
|
3
3
|
import { ProjectJSON, TrackJSON } from '../types';
|
|
4
4
|
import { TimelineEditor } from '../core/editor/timeline.editor';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Type definition for the Timeline context.
|
|
8
|
+
* Contains all the state and functions needed to manage a timeline instance.
|
|
9
|
+
* Provides access to the timeline editor, selected items, undo/redo functionality,
|
|
10
|
+
* and timeline actions.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```js
|
|
14
|
+
* const {
|
|
15
|
+
* editor,
|
|
16
|
+
* selectedItem,
|
|
17
|
+
* totalDuration,
|
|
18
|
+
* canUndo,
|
|
19
|
+
* canRedo,
|
|
20
|
+
* setSelectedItem,
|
|
21
|
+
* setTimelineAction
|
|
22
|
+
* } = useTimelineContext();
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
6
25
|
export type TimelineContextType = {
|
|
26
|
+
/** Unique identifier for this timeline context */
|
|
7
27
|
contextId: string;
|
|
28
|
+
/** The timeline editor instance for this context */
|
|
8
29
|
editor: TimelineEditor;
|
|
30
|
+
/** Currently selected track or element */
|
|
9
31
|
selectedItem: Track | TrackElement | null;
|
|
32
|
+
/** Change counter for tracking modifications */
|
|
10
33
|
changeLog: number;
|
|
34
|
+
/** Current timeline action being performed */
|
|
11
35
|
timelineAction: {
|
|
12
36
|
type: string;
|
|
13
37
|
payload: any;
|
|
14
38
|
};
|
|
39
|
+
/** Total duration of the timeline in seconds */
|
|
15
40
|
totalDuration: number;
|
|
41
|
+
/** Current project state */
|
|
16
42
|
present: ProjectJSON | null;
|
|
43
|
+
/** Whether undo operation is available */
|
|
17
44
|
canUndo: boolean;
|
|
45
|
+
/** Whether redo operation is available */
|
|
18
46
|
canRedo: boolean;
|
|
47
|
+
/** Function to set the selected item */
|
|
19
48
|
setSelectedItem: (item: Track | TrackElement | null) => void;
|
|
49
|
+
/** Function to set timeline actions */
|
|
20
50
|
setTimelineAction: (type: string, payload: any) => void;
|
|
21
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* Props for the TimelineProvider component.
|
|
54
|
+
* Defines the configuration options for timeline context initialization.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```jsx
|
|
58
|
+
* <TimelineProvider
|
|
59
|
+
* contextId="my-timeline"
|
|
60
|
+
* initialData={{ tracks: [], version: 1 }}
|
|
61
|
+
* undoRedoPersistenceKey="timeline-state"
|
|
62
|
+
* maxHistorySize={50}
|
|
63
|
+
* >
|
|
64
|
+
* <YourApp />
|
|
65
|
+
* </TimelineProvider>
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
22
68
|
export interface TimelineProviderProps {
|
|
69
|
+
/** React children to wrap with timeline context */
|
|
23
70
|
children: React.ReactNode;
|
|
71
|
+
/** Unique identifier for this timeline context */
|
|
24
72
|
contextId: string;
|
|
73
|
+
/** Initial timeline data to load */
|
|
25
74
|
initialData?: {
|
|
26
75
|
tracks: TrackJSON[];
|
|
27
76
|
version: number;
|
|
28
77
|
};
|
|
78
|
+
/** Key for persisting undo/redo state */
|
|
29
79
|
undoRedoPersistenceKey?: string;
|
|
80
|
+
/** Maximum number of history states to keep */
|
|
30
81
|
maxHistorySize?: number;
|
|
31
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Provider component for the Timeline context.
|
|
85
|
+
* Wraps the timeline functionality with PostHog analytics and undo/redo support.
|
|
86
|
+
* Manages the global state for timeline instances including tracks, elements,
|
|
87
|
+
* playback state, and history management.
|
|
88
|
+
*
|
|
89
|
+
* @param props - Timeline provider configuration
|
|
90
|
+
* @returns Context provider with timeline state management
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```jsx
|
|
94
|
+
* <TimelineProvider
|
|
95
|
+
* contextId="my-timeline"
|
|
96
|
+
* initialData={{ tracks: [], version: 1 }}
|
|
97
|
+
* undoRedoPersistenceKey="timeline-state"
|
|
98
|
+
* >
|
|
99
|
+
* <YourApp />
|
|
100
|
+
* </TimelineProvider>
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
32
103
|
export declare const TimelineProvider: ({ contextId, children, initialData, undoRedoPersistenceKey, maxHistorySize, }: TimelineProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
104
|
+
/**
|
|
105
|
+
* Hook to access the Timeline context.
|
|
106
|
+
* Provides access to timeline state, editor instance, and timeline management functions.
|
|
107
|
+
* Must be used within a TimelineProvider component.
|
|
108
|
+
*
|
|
109
|
+
* @returns TimelineContextType object with all timeline state and controls
|
|
110
|
+
* @throws Error if used outside of TimelineProvider
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```js
|
|
114
|
+
* const {
|
|
115
|
+
* editor,
|
|
116
|
+
* selectedItem,
|
|
117
|
+
* totalDuration,
|
|
118
|
+
* canUndo,
|
|
119
|
+
* canRedo,
|
|
120
|
+
* setSelectedItem,
|
|
121
|
+
* setTimelineAction
|
|
122
|
+
* } = useTimelineContext();
|
|
123
|
+
*
|
|
124
|
+
* // Access the timeline editor
|
|
125
|
+
* const tracks = editor.getTracks();
|
|
126
|
+
*
|
|
127
|
+
* // Check if undo is available
|
|
128
|
+
* if (canUndo) {
|
|
129
|
+
* editor.undo();
|
|
130
|
+
* }
|
|
131
|
+
*
|
|
132
|
+
* // Set timeline action
|
|
133
|
+
* setTimelineAction(TIMELINE_ACTION.SET_PLAYER_STATE, { playing: true });
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
33
136
|
export declare const useTimelineContext: () => TimelineContextType;
|
|
@@ -2,66 +2,318 @@ import { TrackJSON } from '../../types';
|
|
|
2
2
|
import { TrackElement } from '../elements/base.element';
|
|
3
3
|
import { TrackFriend } from './track.friend';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Track class represents a timeline track that contains multiple elements.
|
|
7
|
+
* A track is a container for timeline elements (video, audio, text, etc.) that
|
|
8
|
+
* can be arranged sequentially or in parallel. Tracks provide validation,
|
|
9
|
+
* serialization, and element management capabilities.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```js
|
|
13
|
+
* import { Track, VideoElement, TextElement } from '@twick/timeline';
|
|
14
|
+
*
|
|
15
|
+
* // Create a new track
|
|
16
|
+
* const videoTrack = new Track("Video Track");
|
|
17
|
+
*
|
|
18
|
+
* // Add elements to the track
|
|
19
|
+
* const videoElement = new VideoElement({
|
|
20
|
+
* src: "video.mp4",
|
|
21
|
+
* start: 0,
|
|
22
|
+
* end: 10
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* videoTrack.createFriend().addElement(videoElement);
|
|
26
|
+
*
|
|
27
|
+
* // Serialize the track
|
|
28
|
+
* const trackData = videoTrack.serialize();
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
5
31
|
export declare class Track {
|
|
6
32
|
private id;
|
|
7
33
|
private name;
|
|
8
34
|
private type;
|
|
9
35
|
private elements;
|
|
10
36
|
private validator;
|
|
37
|
+
/**
|
|
38
|
+
* Creates a new Track instance.
|
|
39
|
+
*
|
|
40
|
+
* @param name - The display name for the track
|
|
41
|
+
* @param id - Optional unique identifier (auto-generated if not provided)
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```js
|
|
45
|
+
* const track = new Track("My Video Track");
|
|
46
|
+
* const trackWithId = new Track("Audio Track", "audio-track-1");
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
11
49
|
constructor(name: string, id?: string);
|
|
12
50
|
/**
|
|
13
|
-
*
|
|
14
|
-
* This implements the Friend Class Pattern
|
|
15
|
-
*
|
|
51
|
+
* Creates a friend instance for explicit access to protected methods.
|
|
52
|
+
* This implements the Friend Class Pattern to allow controlled access
|
|
53
|
+
* to protected methods while maintaining encapsulation.
|
|
54
|
+
*
|
|
55
|
+
* @returns TrackFriend instance that can access protected methods
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```js
|
|
59
|
+
* const track = new Track("My Track");
|
|
60
|
+
* const friend = track.createFriend();
|
|
61
|
+
*
|
|
62
|
+
* // Use friend to add elements
|
|
63
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
64
|
+
* friend.addElement(element);
|
|
65
|
+
* ```
|
|
16
66
|
*/
|
|
17
67
|
createFriend(): TrackFriend;
|
|
18
68
|
/**
|
|
19
|
-
* Friend method to add element (called by TrackFriend)
|
|
20
|
-
*
|
|
21
|
-
*
|
|
69
|
+
* Friend method to add element (called by TrackFriend).
|
|
70
|
+
* Provides controlled access to the protected addElement method.
|
|
71
|
+
*
|
|
72
|
+
* @param element - The element to add to the track
|
|
73
|
+
* @param skipValidation - If true, skips validation (use with caution)
|
|
22
74
|
* @returns true if element was added successfully
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```js
|
|
78
|
+
* const track = new Track("My Track");
|
|
79
|
+
* const friend = track.createFriend();
|
|
80
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
81
|
+
*
|
|
82
|
+
* const success = track.addElementViaFriend(element);
|
|
83
|
+
* // success = true if element was added successfully
|
|
84
|
+
* ```
|
|
23
85
|
*/
|
|
24
86
|
addElementViaFriend(element: TrackElement, skipValidation?: boolean): boolean;
|
|
25
87
|
/**
|
|
26
|
-
* Friend method to remove element (called by TrackFriend)
|
|
27
|
-
*
|
|
88
|
+
* Friend method to remove element (called by TrackFriend).
|
|
89
|
+
* Provides controlled access to the protected removeElement method.
|
|
90
|
+
*
|
|
91
|
+
* @param element - The element to remove from the track
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```js
|
|
95
|
+
* const track = new Track("My Track");
|
|
96
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
97
|
+
*
|
|
98
|
+
* track.removeElementViaFriend(element);
|
|
99
|
+
* // Element is removed from the track
|
|
100
|
+
* ```
|
|
28
101
|
*/
|
|
29
102
|
removeElementViaFriend(element: TrackElement): void;
|
|
30
103
|
/**
|
|
31
|
-
* Friend method to update element (called by TrackFriend)
|
|
32
|
-
*
|
|
104
|
+
* Friend method to update element (called by TrackFriend).
|
|
105
|
+
* Provides controlled access to the protected updateElement method.
|
|
106
|
+
*
|
|
107
|
+
* @param element - The updated element to replace the existing one
|
|
33
108
|
* @returns true if element was updated successfully
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```js
|
|
112
|
+
* const track = new Track("My Track");
|
|
113
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
114
|
+
*
|
|
115
|
+
* // Update the element
|
|
116
|
+
* element.setEnd(15);
|
|
117
|
+
* const success = track.updateElementViaFriend(element);
|
|
118
|
+
* // success = true if element was updated successfully
|
|
119
|
+
* ```
|
|
34
120
|
*/
|
|
35
121
|
updateElementViaFriend(element: TrackElement): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Gets the unique identifier of the track.
|
|
124
|
+
*
|
|
125
|
+
* @returns The track's unique ID string
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```js
|
|
129
|
+
* const track = new Track("My Track", "track-123");
|
|
130
|
+
* const id = track.getId(); // "track-123"
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
36
133
|
getId(): string;
|
|
134
|
+
/**
|
|
135
|
+
* Gets the display name of the track.
|
|
136
|
+
*
|
|
137
|
+
* @returns The track's display name
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```js
|
|
141
|
+
* const track = new Track("Video Track");
|
|
142
|
+
* const name = track.getName(); // "Video Track"
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
37
145
|
getName(): string;
|
|
146
|
+
/**
|
|
147
|
+
* Gets the type of the track.
|
|
148
|
+
*
|
|
149
|
+
* @returns The track's type string
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```js
|
|
153
|
+
* const track = new Track("My Track");
|
|
154
|
+
* const type = track.getType(); // "element"
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
38
157
|
getType(): string;
|
|
158
|
+
/**
|
|
159
|
+
* Gets a read-only array of all elements in the track.
|
|
160
|
+
* Returns a copy of the elements array to prevent external modification.
|
|
161
|
+
*
|
|
162
|
+
* @returns Read-only array of track elements
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```js
|
|
166
|
+
* const track = new Track("My Track");
|
|
167
|
+
* const elements = track.getElements();
|
|
168
|
+
* // elements is a read-only array of TrackElement instances
|
|
169
|
+
*
|
|
170
|
+
* elements.forEach(element => {
|
|
171
|
+
* console.log(`Element: ${element.getId()}, Duration: ${element.getEnd() - element.getStart()}`);
|
|
172
|
+
* });
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
39
175
|
getElements(): ReadonlyArray<TrackElement>;
|
|
40
176
|
/**
|
|
41
|
-
* Validates
|
|
42
|
-
*
|
|
177
|
+
* Validates a single element using the track's validator.
|
|
178
|
+
* Checks if the element meets all validation requirements.
|
|
179
|
+
*
|
|
180
|
+
* @param element - The element to validate
|
|
43
181
|
* @returns true if valid, throws ValidationError if invalid
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```js
|
|
185
|
+
* const track = new Track("My Track");
|
|
186
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
187
|
+
*
|
|
188
|
+
* try {
|
|
189
|
+
* const isValid = track.validateElement(element);
|
|
190
|
+
* console.log('Element is valid:', isValid);
|
|
191
|
+
* } catch (error) {
|
|
192
|
+
* if (error instanceof ValidationError) {
|
|
193
|
+
* console.log('Validation failed:', error.errors);
|
|
194
|
+
* }
|
|
195
|
+
* }
|
|
196
|
+
* ```
|
|
44
197
|
*/
|
|
45
198
|
validateElement(element: TrackElement): boolean;
|
|
199
|
+
/**
|
|
200
|
+
* Gets the total duration of the track.
|
|
201
|
+
* Calculates the duration based on the end time of the last element.
|
|
202
|
+
*
|
|
203
|
+
* @returns The total duration of the track in seconds
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```js
|
|
207
|
+
* const track = new Track("My Track");
|
|
208
|
+
* const duration = track.getTrackDuration(); // 0 if no elements
|
|
209
|
+
*
|
|
210
|
+
* // After adding elements
|
|
211
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 30 });
|
|
212
|
+
* track.createFriend().addElement(element);
|
|
213
|
+
* const newDuration = track.getTrackDuration(); // 30
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
46
216
|
getTrackDuration(): number;
|
|
47
217
|
/**
|
|
48
|
-
* Adds an element to the track with validation
|
|
49
|
-
*
|
|
50
|
-
*
|
|
218
|
+
* Adds an element to the track with validation.
|
|
219
|
+
* Protected method that should be accessed through TrackFriend.
|
|
220
|
+
*
|
|
221
|
+
* @param element - The element to add to the track
|
|
222
|
+
* @param skipValidation - If true, skips validation (use with caution)
|
|
51
223
|
* @returns true if element was added successfully, throws ValidationError if validation fails
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```js
|
|
227
|
+
* const track = new Track("My Track");
|
|
228
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
229
|
+
*
|
|
230
|
+
* // Use friend to access this protected method
|
|
231
|
+
* const friend = track.createFriend();
|
|
232
|
+
* const success = friend.addElement(element);
|
|
233
|
+
* ```
|
|
52
234
|
*/
|
|
53
235
|
protected addElement(element: TrackElement, skipValidation?: boolean): boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Removes an element from the track.
|
|
238
|
+
* Protected method that should be accessed through TrackFriend.
|
|
239
|
+
*
|
|
240
|
+
* @param element - The element to remove from the track
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```js
|
|
244
|
+
* const track = new Track("My Track");
|
|
245
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
246
|
+
*
|
|
247
|
+
* // Use friend to access this protected method
|
|
248
|
+
* const friend = track.createFriend();
|
|
249
|
+
* friend.removeElement(element);
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
54
252
|
protected removeElement(element: TrackElement): void;
|
|
55
253
|
/**
|
|
56
|
-
* Updates an element in the track with validation
|
|
57
|
-
*
|
|
254
|
+
* Updates an element in the track with validation.
|
|
255
|
+
* Protected method that should be accessed through TrackFriend.
|
|
256
|
+
*
|
|
257
|
+
* @param element - The updated element to replace the existing one
|
|
58
258
|
* @returns true if element was updated successfully, throws ValidationError if validation fails
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```js
|
|
262
|
+
* const track = new Track("My Track");
|
|
263
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
264
|
+
*
|
|
265
|
+
* // Use friend to access this protected method
|
|
266
|
+
* const friend = track.createFriend();
|
|
267
|
+
* element.setEnd(15);
|
|
268
|
+
* const success = friend.updateElement(element);
|
|
269
|
+
* ```
|
|
59
270
|
*/
|
|
60
271
|
protected updateElement(element: TrackElement): boolean;
|
|
272
|
+
/**
|
|
273
|
+
* Finds an element in the track by its ID.
|
|
274
|
+
*
|
|
275
|
+
* @param id - The unique identifier of the element to find
|
|
276
|
+
* @returns The found element or undefined if not found
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```js
|
|
280
|
+
* const track = new Track("My Track");
|
|
281
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
282
|
+
* track.createFriend().addElement(element);
|
|
283
|
+
*
|
|
284
|
+
* const foundElement = track.getElementById(element.getId());
|
|
285
|
+
* // foundElement is the same element instance
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
61
288
|
getElementById(id: string): Readonly<TrackElement> | undefined;
|
|
62
289
|
/**
|
|
63
|
-
* Validates all elements in the track and returns combined result and per-element status
|
|
290
|
+
* Validates all elements in the track and returns combined result and per-element status.
|
|
291
|
+
* Provides detailed validation information for each element including errors and warnings.
|
|
292
|
+
*
|
|
64
293
|
* @returns Object with overall isValid and array of per-element validation results
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```js
|
|
297
|
+
* const track = new Track("My Track");
|
|
298
|
+
* const element1 = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
299
|
+
* const element2 = new TextElement({ text: "Hello", start: 5, end: 15 });
|
|
300
|
+
*
|
|
301
|
+
* track.createFriend().addElement(element1);
|
|
302
|
+
* track.createFriend().addElement(element2);
|
|
303
|
+
*
|
|
304
|
+
* const validation = track.validateAllElements();
|
|
305
|
+
* console.log('Overall valid:', validation.isValid);
|
|
306
|
+
*
|
|
307
|
+
* validation.results.forEach(result => {
|
|
308
|
+
* console.log(`Element ${result.element.getId()}: ${result.isValid ? 'Valid' : 'Invalid'}`);
|
|
309
|
+
* if (result.errors) {
|
|
310
|
+
* console.log('Errors:', result.errors);
|
|
311
|
+
* }
|
|
312
|
+
* if (result.warnings) {
|
|
313
|
+
* console.log('Warnings:', result.warnings);
|
|
314
|
+
* }
|
|
315
|
+
* });
|
|
316
|
+
* ```
|
|
65
317
|
*/
|
|
66
318
|
validateAllElements(): {
|
|
67
319
|
isValid: boolean;
|
|
@@ -72,6 +324,59 @@ export declare class Track {
|
|
|
72
324
|
warnings?: string[];
|
|
73
325
|
}>;
|
|
74
326
|
};
|
|
327
|
+
/**
|
|
328
|
+
* Serializes the track and all its elements to JSON format.
|
|
329
|
+
* Converts the track structure to a format that can be stored or transmitted.
|
|
330
|
+
*
|
|
331
|
+
* @returns TrackJSON object representing the track and its elements
|
|
332
|
+
*
|
|
333
|
+
* @example
|
|
334
|
+
* ```js
|
|
335
|
+
* const track = new Track("My Track");
|
|
336
|
+
* const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
|
|
337
|
+
* track.createFriend().addElement(element);
|
|
338
|
+
*
|
|
339
|
+
* const trackData = track.serialize();
|
|
340
|
+
* // trackData = {
|
|
341
|
+
* // id: "t-abc123",
|
|
342
|
+
* // name: "My Track",
|
|
343
|
+
* // type: "element",
|
|
344
|
+
* // elements: [{ ... }]
|
|
345
|
+
* // }
|
|
346
|
+
*
|
|
347
|
+
* // Save to localStorage
|
|
348
|
+
* localStorage.setItem('track-data', JSON.stringify(trackData));
|
|
349
|
+
* ```
|
|
350
|
+
*/
|
|
75
351
|
serialize(): TrackJSON;
|
|
352
|
+
/**
|
|
353
|
+
* Creates a Track instance from JSON data.
|
|
354
|
+
* Static factory method for deserializing track data.
|
|
355
|
+
*
|
|
356
|
+
* @param json - JSON object containing track data
|
|
357
|
+
* @returns New Track instance with loaded data
|
|
358
|
+
*
|
|
359
|
+
* @example
|
|
360
|
+
* ```js
|
|
361
|
+
* const trackData = {
|
|
362
|
+
* id: "t-abc123",
|
|
363
|
+
* name: "My Track",
|
|
364
|
+
* type: "element",
|
|
365
|
+
* elements: [
|
|
366
|
+
* {
|
|
367
|
+
* id: "e-def456",
|
|
368
|
+
* type: "video",
|
|
369
|
+
* src: "video.mp4",
|
|
370
|
+
* start: 0,
|
|
371
|
+
* end: 10
|
|
372
|
+
* }
|
|
373
|
+
* ]
|
|
374
|
+
* };
|
|
375
|
+
*
|
|
376
|
+
* const track = Track.fromJSON(trackData);
|
|
377
|
+
* console.log(track.getName()); // "My Track"
|
|
378
|
+
* console.log(track.getElements().length); // 1
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
76
381
|
static fromJSON(json: any): Track;
|
|
77
382
|
}
|