@twick/timeline 0.14.2 → 0.14.4

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.
@@ -2,66 +2,319 @@ 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;
11
- constructor(name: string, id?: string);
12
37
  /**
13
- * Create a friend instance for explicit access to protected methods
14
- * This implements the Friend Class Pattern
15
- * @returns TrackFriend instance
38
+ * Creates a new Track instance.
39
+ *
40
+ * @param name - The display name for the track
41
+ * @param type - The type of the track
42
+ * @param id - Optional unique identifier (auto-generated if not provided)
43
+ *
44
+ * @example
45
+ * ```js
46
+ * const track = new Track("My Video Track");
47
+ * const trackWithId = new Track("Audio Track", "element", "video-track-1");
48
+ * ```
49
+ */
50
+ constructor(name: string, type?: string, id?: string);
51
+ /**
52
+ * Creates a friend instance for explicit access to protected methods.
53
+ * This implements the Friend Class Pattern to allow controlled access
54
+ * to protected methods while maintaining encapsulation.
55
+ *
56
+ * @returns TrackFriend instance that can access protected methods
57
+ *
58
+ * @example
59
+ * ```js
60
+ * const track = new Track("My Track");
61
+ * const friend = track.createFriend();
62
+ *
63
+ * // Use friend to add elements
64
+ * const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
65
+ * friend.addElement(element);
66
+ * ```
16
67
  */
17
68
  createFriend(): TrackFriend;
18
69
  /**
19
- * Friend method to add element (called by TrackFriend)
20
- * @param element The element to add
21
- * @param skipValidation If true, skips validation
70
+ * Friend method to add element (called by TrackFriend).
71
+ * Provides controlled access to the protected addElement method.
72
+ *
73
+ * @param element - The element to add to the track
74
+ * @param skipValidation - If true, skips validation (use with caution)
22
75
  * @returns true if element was added successfully
76
+ *
77
+ * @example
78
+ * ```js
79
+ * const track = new Track("My Track");
80
+ * const friend = track.createFriend();
81
+ * const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
82
+ *
83
+ * const success = track.addElementViaFriend(element);
84
+ * // success = true if element was added successfully
85
+ * ```
23
86
  */
24
87
  addElementViaFriend(element: TrackElement, skipValidation?: boolean): boolean;
25
88
  /**
26
- * Friend method to remove element (called by TrackFriend)
27
- * @param element The element to remove
89
+ * Friend method to remove element (called by TrackFriend).
90
+ * Provides controlled access to the protected removeElement method.
91
+ *
92
+ * @param element - The element to remove from the track
93
+ *
94
+ * @example
95
+ * ```js
96
+ * const track = new Track("My Track");
97
+ * const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
98
+ *
99
+ * track.removeElementViaFriend(element);
100
+ * // Element is removed from the track
101
+ * ```
28
102
  */
29
103
  removeElementViaFriend(element: TrackElement): void;
30
104
  /**
31
- * Friend method to update element (called by TrackFriend)
32
- * @param element The element to update
105
+ * Friend method to update element (called by TrackFriend).
106
+ * Provides controlled access to the protected updateElement method.
107
+ *
108
+ * @param element - The updated element to replace the existing one
33
109
  * @returns true if element was updated successfully
110
+ *
111
+ * @example
112
+ * ```js
113
+ * const track = new Track("My Track");
114
+ * const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
115
+ *
116
+ * // Update the element
117
+ * element.setEnd(15);
118
+ * const success = track.updateElementViaFriend(element);
119
+ * // success = true if element was updated successfully
120
+ * ```
34
121
  */
35
122
  updateElementViaFriend(element: TrackElement): boolean;
123
+ /**
124
+ * Gets the unique identifier of the track.
125
+ *
126
+ * @returns The track's unique ID string
127
+ *
128
+ * @example
129
+ * ```js
130
+ * const track = new Track("My Track", "element", "track-123");
131
+ * const id = track.getId(); // "track-123"
132
+ * ```
133
+ */
36
134
  getId(): string;
135
+ /**
136
+ * Gets the display name of the track.
137
+ *
138
+ * @returns The track's display name
139
+ *
140
+ * @example
141
+ * ```js
142
+ * const track = new Track("Video Track");
143
+ * const name = track.getName(); // "Video Track"
144
+ * ```
145
+ */
37
146
  getName(): string;
147
+ /**
148
+ * Gets the type of the track.
149
+ *
150
+ * @returns The track's type string
151
+ *
152
+ * @example
153
+ * ```js
154
+ * const track = new Track("My Track");
155
+ * const type = track.getType(); // "element"
156
+ * ```
157
+ */
38
158
  getType(): string;
159
+ /**
160
+ * Gets a read-only array of all elements in the track.
161
+ * Returns a copy of the elements array to prevent external modification.
162
+ *
163
+ * @returns Read-only array of track elements
164
+ *
165
+ * @example
166
+ * ```js
167
+ * const track = new Track("My Track");
168
+ * const elements = track.getElements();
169
+ * // elements is a read-only array of TrackElement instances
170
+ *
171
+ * elements.forEach(element => {
172
+ * console.log(`Element: ${element.getId()}, Duration: ${element.getEnd() - element.getStart()}`);
173
+ * });
174
+ * ```
175
+ */
39
176
  getElements(): ReadonlyArray<TrackElement>;
40
177
  /**
41
- * Validates an element
42
- * @param element The element to validate
178
+ * Validates a single element using the track's validator.
179
+ * Checks if the element meets all validation requirements.
180
+ *
181
+ * @param element - The element to validate
43
182
  * @returns true if valid, throws ValidationError if invalid
183
+ *
184
+ * @example
185
+ * ```js
186
+ * const track = new Track("My Track");
187
+ * const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
188
+ *
189
+ * try {
190
+ * const isValid = track.validateElement(element);
191
+ * console.log('Element is valid:', isValid);
192
+ * } catch (error) {
193
+ * if (error instanceof ValidationError) {
194
+ * console.log('Validation failed:', error.errors);
195
+ * }
196
+ * }
197
+ * ```
44
198
  */
45
199
  validateElement(element: TrackElement): boolean;
200
+ /**
201
+ * Gets the total duration of the track.
202
+ * Calculates the duration based on the end time of the last element.
203
+ *
204
+ * @returns The total duration of the track in seconds
205
+ *
206
+ * @example
207
+ * ```js
208
+ * const track = new Track("My Track");
209
+ * const duration = track.getTrackDuration(); // 0 if no elements
210
+ *
211
+ * // After adding elements
212
+ * const element = new VideoElement({ src: "video.mp4", start: 0, end: 30 });
213
+ * track.createFriend().addElement(element);
214
+ * const newDuration = track.getTrackDuration(); // 30
215
+ * ```
216
+ */
46
217
  getTrackDuration(): number;
47
218
  /**
48
- * Adds an element to the track with validation
49
- * @param element The element to add
50
- * @param skipValidation If true, skips validation (use with caution)
219
+ * Adds an element to the track with validation.
220
+ * Protected method that should be accessed through TrackFriend.
221
+ *
222
+ * @param element - The element to add to the track
223
+ * @param skipValidation - If true, skips validation (use with caution)
51
224
  * @returns true if element was added successfully, throws ValidationError if validation fails
225
+ *
226
+ * @example
227
+ * ```js
228
+ * const track = new Track("My Track");
229
+ * const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
230
+ *
231
+ * // Use friend to access this protected method
232
+ * const friend = track.createFriend();
233
+ * const success = friend.addElement(element);
234
+ * ```
52
235
  */
53
236
  protected addElement(element: TrackElement, skipValidation?: boolean): boolean;
237
+ /**
238
+ * Removes an element from the track.
239
+ * Protected method that should be accessed through TrackFriend.
240
+ *
241
+ * @param element - The element to remove from the track
242
+ *
243
+ * @example
244
+ * ```js
245
+ * const track = new Track("My Track");
246
+ * const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
247
+ *
248
+ * // Use friend to access this protected method
249
+ * const friend = track.createFriend();
250
+ * friend.removeElement(element);
251
+ * ```
252
+ */
54
253
  protected removeElement(element: TrackElement): void;
55
254
  /**
56
- * Updates an element in the track with validation
57
- * @param element The element to update
255
+ * Updates an element in the track with validation.
256
+ * Protected method that should be accessed through TrackFriend.
257
+ *
258
+ * @param element - The updated element to replace the existing one
58
259
  * @returns true if element was updated successfully, throws ValidationError if validation fails
260
+ *
261
+ * @example
262
+ * ```js
263
+ * const track = new Track("My Track");
264
+ * const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
265
+ *
266
+ * // Use friend to access this protected method
267
+ * const friend = track.createFriend();
268
+ * element.setEnd(15);
269
+ * const success = friend.updateElement(element);
270
+ * ```
59
271
  */
60
272
  protected updateElement(element: TrackElement): boolean;
273
+ /**
274
+ * Finds an element in the track by its ID.
275
+ *
276
+ * @param id - The unique identifier of the element to find
277
+ * @returns The found element or undefined if not found
278
+ *
279
+ * @example
280
+ * ```js
281
+ * const track = new Track("My Track");
282
+ * const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
283
+ * track.createFriend().addElement(element);
284
+ *
285
+ * const foundElement = track.getElementById(element.getId());
286
+ * // foundElement is the same element instance
287
+ * ```
288
+ */
61
289
  getElementById(id: string): Readonly<TrackElement> | undefined;
62
290
  /**
63
- * Validates all elements in the track and returns combined result and per-element status
291
+ * Validates all elements in the track and returns combined result and per-element status.
292
+ * Provides detailed validation information for each element including errors and warnings.
293
+ *
64
294
  * @returns Object with overall isValid and array of per-element validation results
295
+ *
296
+ * @example
297
+ * ```js
298
+ * const track = new Track("My Track");
299
+ * const element1 = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
300
+ * const element2 = new TextElement({ text: "Hello", start: 5, end: 15 });
301
+ *
302
+ * track.createFriend().addElement(element1);
303
+ * track.createFriend().addElement(element2);
304
+ *
305
+ * const validation = track.validateAllElements();
306
+ * console.log('Overall valid:', validation.isValid);
307
+ *
308
+ * validation.results.forEach(result => {
309
+ * console.log(`Element ${result.element.getId()}: ${result.isValid ? 'Valid' : 'Invalid'}`);
310
+ * if (result.errors) {
311
+ * console.log('Errors:', result.errors);
312
+ * }
313
+ * if (result.warnings) {
314
+ * console.log('Warnings:', result.warnings);
315
+ * }
316
+ * });
317
+ * ```
65
318
  */
66
319
  validateAllElements(): {
67
320
  isValid: boolean;
@@ -72,6 +325,59 @@ export declare class Track {
72
325
  warnings?: string[];
73
326
  }>;
74
327
  };
328
+ /**
329
+ * Serializes the track and all its elements to JSON format.
330
+ * Converts the track structure to a format that can be stored or transmitted.
331
+ *
332
+ * @returns TrackJSON object representing the track and its elements
333
+ *
334
+ * @example
335
+ * ```js
336
+ * const track = new Track("My Track");
337
+ * const element = new VideoElement({ src: "video.mp4", start: 0, end: 10 });
338
+ * track.createFriend().addElement(element);
339
+ *
340
+ * const trackData = track.serialize();
341
+ * // trackData = {
342
+ * // id: "t-abc123",
343
+ * // name: "My Track",
344
+ * // type: "element",
345
+ * // elements: [{ ... }]
346
+ * // }
347
+ *
348
+ * // Save to localStorage
349
+ * localStorage.setItem('track-data', JSON.stringify(trackData));
350
+ * ```
351
+ */
75
352
  serialize(): TrackJSON;
353
+ /**
354
+ * Creates a Track instance from JSON data.
355
+ * Static factory method for deserializing track data.
356
+ *
357
+ * @param json - JSON object containing track data
358
+ * @returns New Track instance with loaded data
359
+ *
360
+ * @example
361
+ * ```js
362
+ * const trackData = {
363
+ * id: "t-abc123",
364
+ * name: "My Track",
365
+ * type: "element",
366
+ * elements: [
367
+ * {
368
+ * id: "e-def456",
369
+ * type: "video",
370
+ * src: "video.mp4",
371
+ * start: 0,
372
+ * end: 10
373
+ * }
374
+ * ]
375
+ * };
376
+ *
377
+ * const track = Track.fromJSON(trackData);
378
+ * console.log(track.getName()); // "My Track"
379
+ * console.log(track.getElements().length); // 1
380
+ * ```
381
+ */
76
382
  static fromJSON(json: any): Track;
77
383
  }
@@ -10,20 +10,140 @@ import { RectElement } from '../elements/rect.element';
10
10
  import { Track } from '../track/track';
11
11
 
12
12
  /**
13
- * ElementAdder visitor for adding elements to tracks
13
+ * ElementAdder visitor for adding elements to tracks.
14
14
  * Uses the visitor pattern to handle different element types
15
- * Implements the Friend Class Pattern for explicit access control
15
+ * and implements the Friend Class Pattern for explicit access control.
16
+ * Automatically calculates start and end times for elements based on
17
+ * existing track content.
16
18
  */
17
19
  export declare class ElementAdder implements ElementVisitor<Promise<boolean>> {
18
20
  private track;
19
21
  private trackFriend;
22
+ /**
23
+ * Creates a new ElementAdder instance for the specified track.
24
+ *
25
+ * @param track - The track to add elements to
26
+ *
27
+ * @example
28
+ * ```js
29
+ * const adder = new ElementAdder(track);
30
+ * const success = await adder.visitVideoElement(videoElement);
31
+ * ```
32
+ */
20
33
  constructor(track: Track);
34
+ /**
35
+ * Adds a video element to the track.
36
+ * Updates video metadata and calculates appropriate start/end times
37
+ * based on existing track elements.
38
+ *
39
+ * @param element - The video element to add
40
+ * @returns Promise resolving to true if element was added successfully
41
+ *
42
+ * @example
43
+ * ```js
44
+ * const success = await adder.visitVideoElement(videoElement);
45
+ * // success = true if element was added successfully
46
+ * ```
47
+ */
21
48
  visitVideoElement(element: VideoElement): Promise<boolean>;
49
+ /**
50
+ * Adds an audio element to the track.
51
+ * Updates audio metadata and calculates appropriate start/end times
52
+ * based on existing track elements.
53
+ *
54
+ * @param element - The audio element to add
55
+ * @returns Promise resolving to true if element was added successfully
56
+ *
57
+ * @example
58
+ * ```js
59
+ * const success = await adder.visitAudioElement(audioElement);
60
+ * // success = true if element was added successfully
61
+ * ```
62
+ */
22
63
  visitAudioElement(element: AudioElement): Promise<boolean>;
64
+ /**
65
+ * Adds an image element to the track.
66
+ * Updates image metadata and calculates appropriate start/end times
67
+ * based on existing track elements.
68
+ *
69
+ * @param element - The image element to add
70
+ * @returns Promise resolving to true if element was added successfully
71
+ *
72
+ * @example
73
+ * ```js
74
+ * const success = await adder.visitImageElement(imageElement);
75
+ * // success = true if element was added successfully
76
+ * ```
77
+ */
23
78
  visitImageElement(element: ImageElement): Promise<boolean>;
79
+ /**
80
+ * Adds a text element to the track.
81
+ * Calculates appropriate start/end times based on existing track elements.
82
+ *
83
+ * @param element - The text element to add
84
+ * @returns Promise resolving to true if element was added successfully
85
+ *
86
+ * @example
87
+ * ```js
88
+ * const success = await adder.visitTextElement(textElement);
89
+ * // success = true if element was added successfully
90
+ * ```
91
+ */
24
92
  visitTextElement(element: TextElement): Promise<boolean>;
93
+ /**
94
+ * Adds a caption element to the track.
95
+ * Calculates appropriate start/end times based on existing track elements.
96
+ *
97
+ * @param element - The caption element to add
98
+ * @returns Promise resolving to true if element was added successfully
99
+ *
100
+ * @example
101
+ * ```js
102
+ * const success = await adder.visitCaptionElement(captionElement);
103
+ * // success = true if element was added successfully
104
+ * ```
105
+ */
25
106
  visitCaptionElement(element: CaptionElement): Promise<boolean>;
107
+ /**
108
+ * Adds an icon element to the track.
109
+ * Calculates appropriate start/end times based on existing track elements.
110
+ *
111
+ * @param element - The icon element to add
112
+ * @returns Promise resolving to true if element was added successfully
113
+ *
114
+ * @example
115
+ * ```js
116
+ * const success = await adder.visitIconElement(iconElement);
117
+ * // success = true if element was added successfully
118
+ * ```
119
+ */
26
120
  visitIconElement(element: IconElement): Promise<boolean>;
121
+ /**
122
+ * Adds a circle element to the track.
123
+ * Calculates appropriate start/end times based on existing track elements.
124
+ *
125
+ * @param element - The circle element to add
126
+ * @returns Promise resolving to true if element was added successfully
127
+ *
128
+ * @example
129
+ * ```js
130
+ * const success = await adder.visitCircleElement(circleElement);
131
+ * // success = true if element was added successfully
132
+ * ```
133
+ */
27
134
  visitCircleElement(element: CircleElement): Promise<boolean>;
135
+ /**
136
+ * Adds a rectangle element to the track.
137
+ * Calculates appropriate start/end times based on existing track elements.
138
+ *
139
+ * @param element - The rectangle element to add
140
+ * @returns Promise resolving to true if element was added successfully
141
+ *
142
+ * @example
143
+ * ```js
144
+ * const success = await adder.visitRectElement(rectElement);
145
+ * // success = true if element was added successfully
146
+ * ```
147
+ */
28
148
  visitRectElement(element: RectElement): Promise<boolean>;
29
149
  }