@dawcore/components 0.0.12 → 0.0.14

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/dist/index.d.mts CHANGED
@@ -18,6 +18,9 @@ declare class DawClipElement extends LitElement {
18
18
  fadeType: string;
19
19
  readonly clipId: `${string}-${string}-${string}-${string}-${string}`;
20
20
  createRenderRoot(): this;
21
+ connectedCallback(): void;
22
+ private _hasRendered;
23
+ updated(changed: PropertyValues): void;
21
24
  }
22
25
  declare global {
23
26
  interface HTMLElementTagNameMap {
@@ -201,7 +204,10 @@ interface TrackDescriptor {
201
204
  soloed: boolean;
202
205
  clips: ClipDescriptor[];
203
206
  }
204
- interface ClipDescriptor {
207
+ /**
208
+ * Common fields shared by all clip descriptors regardless of source.
209
+ */
210
+ interface BaseClipDescriptor {
205
211
  src: string;
206
212
  peaksSrc: string;
207
213
  start: number;
@@ -213,6 +219,62 @@ interface ClipDescriptor {
213
219
  fadeOut: number;
214
220
  fadeType: FadeType;
215
221
  }
222
+ /**
223
+ * A clip descriptor sourced from a `<daw-clip>` DOM element. `clipId` is
224
+ * always set — `<daw-clip>.clipId` is a `crypto.randomUUID()` generated at
225
+ * construction. Engine `clip.id` is aligned with this id in `_loadTrack`
226
+ * and `_loadAndAppendClip` so DOM and engine reference the same clip.
227
+ */
228
+ interface DomClipDescriptor extends BaseClipDescriptor {
229
+ kind: 'dom';
230
+ clipId: string;
231
+ }
232
+ /**
233
+ * A clip descriptor synthesized from a non-DOM source — file drops, the
234
+ * `<daw-track src>` shorthand fallback, or recording-clip insertion. No
235
+ * `clipId` because there's no DOM element to align with; the engine
236
+ * generates its own id at clip-creation time.
237
+ */
238
+ interface DropClipDescriptor extends BaseClipDescriptor {
239
+ kind: 'drop';
240
+ }
241
+ type ClipDescriptor = DomClipDescriptor | DropClipDescriptor;
242
+ /**
243
+ * Type predicate for the `'dom'` discriminator. Use to narrow a
244
+ * `ClipDescriptor` to `DomClipDescriptor` (which has `clipId`) without
245
+ * inline `c.kind === 'dom'` repetition.
246
+ */
247
+ declare function isDomClip(desc: ClipDescriptor): desc is DomClipDescriptor;
248
+ /**
249
+ * Public input shape for `editor.addTrack(config)`. All fields optional —
250
+ * defaults match the declarative `<daw-track>` defaults.
251
+ */
252
+ interface TrackConfig {
253
+ name?: string;
254
+ volume?: number;
255
+ pan?: number;
256
+ muted?: boolean;
257
+ soloed?: boolean;
258
+ clips?: ClipConfig[];
259
+ }
260
+ /**
261
+ * Public input shape for clips passed via `TrackConfig.clips` or
262
+ * `editor.addClip(trackId, config)`. `src` is required — every clip needs
263
+ * an audio source to load. Other fields default to the matching
264
+ * `<daw-clip>` attribute defaults.
265
+ */
266
+ interface ClipConfig {
267
+ src: string;
268
+ peaksSrc?: string;
269
+ start?: number;
270
+ duration?: number;
271
+ offset?: number;
272
+ gain?: number;
273
+ name?: string;
274
+ fadeIn?: number;
275
+ fadeOut?: number;
276
+ fadeType?: FadeType;
277
+ }
216
278
 
217
279
  /**
218
280
  * Peak generation pipeline: AudioBuffer → web worker → WaveformData → PeakData.
@@ -584,6 +646,23 @@ interface DawRecordingErrorDetail {
584
646
  trackId: string;
585
647
  error: unknown;
586
648
  }
649
+ interface DawClipConnectedDetail {
650
+ clipId: string;
651
+ element: DawClipElement;
652
+ }
653
+ interface DawClipIdDetail {
654
+ trackId: string;
655
+ clipId: string;
656
+ }
657
+ interface DawClipUpdateDetail {
658
+ trackId: string;
659
+ clipId: string;
660
+ }
661
+ interface DawClipErrorDetail {
662
+ trackId: string;
663
+ clipId: string;
664
+ error: unknown;
665
+ }
587
666
  interface DawClipMoveDetail {
588
667
  readonly trackId: string;
589
668
  readonly clipId: string;
@@ -623,6 +702,10 @@ interface DawEventMap {
623
702
  'daw-recording-start': CustomEvent<DawRecordingStartDetail>;
624
703
  'daw-recording-complete': CustomEvent<DawRecordingCompleteDetail>;
625
704
  'daw-recording-error': CustomEvent<DawRecordingErrorDetail>;
705
+ 'daw-clip-connected': CustomEvent<DawClipConnectedDetail>;
706
+ 'daw-clip-update': CustomEvent<DawClipUpdateDetail>;
707
+ 'daw-clip-ready': CustomEvent<DawClipIdDetail>;
708
+ 'daw-clip-error': CustomEvent<DawClipErrorDetail>;
626
709
  'daw-clip-move': CustomEvent<DawClipMoveDetail>;
627
710
  'daw-clip-trim': CustomEvent<DawClipTrimDetail>;
628
711
  'daw-clip-split': CustomEvent<DawClipSplitDetail>;
@@ -649,6 +732,13 @@ declare class DawEditorElement extends LitElement {
649
732
  clipHeaders: boolean;
650
733
  clipHeaderHeight: number;
651
734
  interactiveClips: boolean;
735
+ /**
736
+ * When true, the timeline fills the visible viewport even if total clip
737
+ * duration is less. Lets the ruler render before any audio is loaded —
738
+ * useful for empty editors and recording UIs. In beats mode the 32-bar
739
+ * floor already provides this; this attribute controls the temporal mode.
740
+ */
741
+ indefinitePlayback: boolean;
652
742
  scaleMode: 'temporal' | 'beats';
653
743
  get ticksPerPixel(): number;
654
744
  set ticksPerPixel(value: number);
@@ -710,10 +800,7 @@ declare class DawEditorElement extends LitElement {
710
800
  get engine(): PlaylistEngine | null;
711
801
  get renderSamplesPerPixel(): number;
712
802
  /** Re-extract peaks for a clip at new offset/duration from cached WaveformData. */
713
- reextractClipPeaks(clipId: string, offsetSamples: number, durationSamples: number): {
714
- data: Peaks[];
715
- length: number;
716
- } | null;
803
+ reextractClipPeaks(clipId: string, offsetSamples: number, durationSamples: number): PeakData | null;
717
804
  private _pointer;
718
805
  private _viewport;
719
806
  static styles: lit.CSSResult[];
@@ -748,6 +835,42 @@ declare class DawEditorElement extends LitElement {
748
835
  private static _CONTROL_PROPS;
749
836
  private _onTrackControl;
750
837
  private _onTrackRemoveRequest;
838
+ private _onClipConnected;
839
+ private _onClipUpdate;
840
+ private _onClipRemovedFromDom;
841
+ private _loadAndAppendClip;
842
+ /**
843
+ * Resolve pre-computed peaks for a clip: fetch the .dat/.json, validate the
844
+ * sample rate matches the AudioContext, return the WaveformData or null.
845
+ * Warns on fetch failure and on sample-rate mismatch — never silent.
846
+ *
847
+ * Shared between `_loadTrack` (peaks-first preview path) and
848
+ * `_loadAndAppendClip` (incremental late-append).
849
+ */
850
+ private _resolvePeaks;
851
+ /**
852
+ * Construct an AudioClip from a decoded buffer (and optional WaveformData),
853
+ * align its id with the source `<daw-clip>.clipId` when present, populate
854
+ * `_clipBuffers` / `_clipOffsets`, generate peaks via the worker pipeline,
855
+ * and populate `_peaksData`. Returns the finished AudioClip.
856
+ *
857
+ * Shared between `_loadTrack`'s standard path and `_loadAndAppendClip`.
858
+ * Not used by `_loadTrack`'s peaks-first preview path because that path
859
+ * uses sync `extractPeaks` and inserts a preview track BEFORE audio decode.
860
+ */
861
+ private _finalizeAudioClip;
862
+ /** Remove a single clip from all per-clip caches. Used by error rollbacks. */
863
+ private _purgeClipCaches;
864
+ /**
865
+ * Recompute duration and forward an updated track to the engine. Single
866
+ * source of truth for the incremental-vs-full-rebuild policy used by every
867
+ * clip-level mutation (addClip, updateClip, removeClip, _applyClipUpdate).
868
+ * Use the engine's incremental updateTrack when available; otherwise fall
869
+ * back to full setTracks (legacy adapters).
870
+ */
871
+ private _commitTrackChange;
872
+ private _applyClipUpdate;
873
+ private _removeClipFromTrack;
751
874
  private _readTrackDescriptor;
752
875
  private _loadTrack;
753
876
  _fetchAndDecode(src: string): Promise<AudioBuffer>;
@@ -760,6 +883,67 @@ declare class DawEditorElement extends LitElement {
760
883
  private _onDragLeave;
761
884
  private _onDrop;
762
885
  loadFiles(files: FileList | File[]): Promise<LoadFilesResult>;
886
+ /**
887
+ * Build the engine if it hasn't been built yet. Lets consumers obtain a
888
+ * non-null `editor.engine` before any track has been loaded — useful for
889
+ * wiring analyzers, effects, or master taps before content arrives.
890
+ */
891
+ ready(): Promise<PlaylistEngine>;
892
+ /**
893
+ * Wait for either `readyEvent` or `errorEvent` to fire on this editor for
894
+ * the entity matching `matchesId`. Listeners are wired synchronously, then
895
+ * `setup` is called (typical: appendChild). Resolves with `resolveValue`
896
+ * on ready; rejects with a normalized Error on error. Used by addTrack and
897
+ * addClip to share their Promise-with-listener-cleanup machinery.
898
+ */
899
+ private _awaitId;
900
+ /**
901
+ * Append a `<daw-track>` element built from `config` and resolve once the
902
+ * track finishes loading (or reject on `daw-track-error`). Goes through
903
+ * the same `_loadTrack` pipeline as declarative tracks, so descriptors,
904
+ * peaks, and clip buffers are populated correctly.
905
+ */
906
+ addTrack(config?: TrackConfig): Promise<DawTrackElement>;
907
+ /**
908
+ * Remove a track by id. Equivalent to `trackElement.remove()` —
909
+ * the editor's MutationObserver handles engine and cache cleanup.
910
+ * No-op if no matching track exists.
911
+ */
912
+ removeTrack(trackId: string): void;
913
+ /**
914
+ * Update reflected attributes on a track. For DOM-element tracks the changes
915
+ * are written to the `<daw-track>` element (which fires `daw-track-update`);
916
+ * for tracks without a DOM element (file drops) the descriptor and engine
917
+ * state are updated in place.
918
+ */
919
+ updateTrack(trackId: string, partial: Partial<TrackConfig>): void;
920
+ /**
921
+ * Append a clip to an existing track. Builds a `<daw-clip>` from `config`
922
+ * and appends it to the track's DOM element when one exists; resolves with
923
+ * the new clip's id once the audio decode + peak generation finish.
924
+ */
925
+ addClip(trackId: string, config: ClipConfig): Promise<string>;
926
+ /**
927
+ * Remove a clip by id. Removes the matching `<daw-clip>` DOM element when
928
+ * present (MutationObserver handles cleanup); otherwise updates engine
929
+ * state directly. No-op if no matching clip exists.
930
+ */
931
+ removeClip(trackId: string, clipId: string): void;
932
+ /**
933
+ * Update a clip's position (start/duration/offset) or properties (gain/name).
934
+ * For DOM-element clips, writes properties on the `<daw-clip>` element which
935
+ * fires `daw-clip-update`; otherwise applies directly via `_applyClipUpdate`.
936
+ *
937
+ * Re-decoding (changing `src`) is not supported via this method — remove and
938
+ * re-add the clip instead.
939
+ *
940
+ * Note: `fadeIn` / `fadeOut` / `fadeType` on the partial are written to the
941
+ * `<daw-clip>` element (so they round-trip in the descriptor), but engine-side
942
+ * fade application from `<daw-clip>` properties is not yet implemented — see
943
+ * the broader fade-engine integration tracked separately.
944
+ */
945
+ updateClip(trackId: string, clipId: string, partial: Partial<ClipConfig>): void;
946
+ private _buildClipElement;
763
947
  play(startTime?: number): Promise<void>;
764
948
  pause(): void;
765
949
  stop(): void;
@@ -965,4 +1149,4 @@ interface SplitHost {
965
1149
  */
966
1150
  declare function splitAtPlayhead(host: SplitHost): boolean;
967
1151
 
968
- export { AudioResumeController, type ClipDescriptor, type ClipEngineContract, ClipPointerHandler, type ClipPointerHost, DawClipElement, type DawClipMoveDetail, type DawClipSplitDetail, type DawClipTrimDetail, DawEditorElement, type DawErrorDetail, type DawEvent, type DawEventMap, type DawFilesLoadErrorDetail, DawGridElement, DawKeyboardShortcutsElement, DawPauseButtonElement, DawPlayButtonElement, DawPlayheadElement, DawRecordButtonElement, type DawRecordingCompleteDetail, type DawRecordingErrorDetail, type DawRecordingStartDetail, DawRulerElement, type DawSeekDetail, type DawSelectionDetail, DawSelectionElement, DawStopButtonElement, type DawTrackConnectedDetail, type DawTrackControlDetail, DawTrackControlsElement, DawTrackElement, type DawTrackErrorDetail, type DawTrackIdDetail, type DawTrackRemoveDetail, type DawTrackSelectDetail, DawTransportButton, DawTransportElement, DawWaveformElement, type KeyBinding, type LoadFilesResult, type PlaybackShortcutMap, type PointerEngineContract, RecordingController, type RecordingOptions, type RecordingSession, type SplitEngineContract, type SplitHost, type SplittingShortcutMap, type TrackDescriptor, type UndoShortcutMap, type WaveformSegment, splitAtPlayhead };
1152
+ export { AudioResumeController, type ClipConfig, type ClipDescriptor, type ClipEngineContract, ClipPointerHandler, type ClipPointerHost, type DawClipConnectedDetail, DawClipElement, type DawClipErrorDetail, type DawClipIdDetail, type DawClipMoveDetail, type DawClipSplitDetail, type DawClipTrimDetail, type DawClipUpdateDetail, DawEditorElement, type DawErrorDetail, type DawEvent, type DawEventMap, type DawFilesLoadErrorDetail, DawGridElement, DawKeyboardShortcutsElement, DawPauseButtonElement, DawPlayButtonElement, DawPlayheadElement, DawRecordButtonElement, type DawRecordingCompleteDetail, type DawRecordingErrorDetail, type DawRecordingStartDetail, DawRulerElement, type DawSeekDetail, type DawSelectionDetail, DawSelectionElement, DawStopButtonElement, type DawTrackConnectedDetail, type DawTrackControlDetail, DawTrackControlsElement, DawTrackElement, type DawTrackErrorDetail, type DawTrackIdDetail, type DawTrackRemoveDetail, type DawTrackSelectDetail, DawTransportButton, DawTransportElement, DawWaveformElement, type DomClipDescriptor, type DropClipDescriptor, type KeyBinding, type LoadFilesResult, type PlaybackShortcutMap, type PointerEngineContract, RecordingController, type RecordingOptions, type RecordingSession, type SplitEngineContract, type SplitHost, type SplittingShortcutMap, type TrackConfig, type TrackDescriptor, type UndoShortcutMap, type WaveformSegment, isDomClip, splitAtPlayhead };
package/dist/index.d.ts CHANGED
@@ -18,6 +18,9 @@ declare class DawClipElement extends LitElement {
18
18
  fadeType: string;
19
19
  readonly clipId: `${string}-${string}-${string}-${string}-${string}`;
20
20
  createRenderRoot(): this;
21
+ connectedCallback(): void;
22
+ private _hasRendered;
23
+ updated(changed: PropertyValues): void;
21
24
  }
22
25
  declare global {
23
26
  interface HTMLElementTagNameMap {
@@ -201,7 +204,10 @@ interface TrackDescriptor {
201
204
  soloed: boolean;
202
205
  clips: ClipDescriptor[];
203
206
  }
204
- interface ClipDescriptor {
207
+ /**
208
+ * Common fields shared by all clip descriptors regardless of source.
209
+ */
210
+ interface BaseClipDescriptor {
205
211
  src: string;
206
212
  peaksSrc: string;
207
213
  start: number;
@@ -213,6 +219,62 @@ interface ClipDescriptor {
213
219
  fadeOut: number;
214
220
  fadeType: FadeType;
215
221
  }
222
+ /**
223
+ * A clip descriptor sourced from a `<daw-clip>` DOM element. `clipId` is
224
+ * always set — `<daw-clip>.clipId` is a `crypto.randomUUID()` generated at
225
+ * construction. Engine `clip.id` is aligned with this id in `_loadTrack`
226
+ * and `_loadAndAppendClip` so DOM and engine reference the same clip.
227
+ */
228
+ interface DomClipDescriptor extends BaseClipDescriptor {
229
+ kind: 'dom';
230
+ clipId: string;
231
+ }
232
+ /**
233
+ * A clip descriptor synthesized from a non-DOM source — file drops, the
234
+ * `<daw-track src>` shorthand fallback, or recording-clip insertion. No
235
+ * `clipId` because there's no DOM element to align with; the engine
236
+ * generates its own id at clip-creation time.
237
+ */
238
+ interface DropClipDescriptor extends BaseClipDescriptor {
239
+ kind: 'drop';
240
+ }
241
+ type ClipDescriptor = DomClipDescriptor | DropClipDescriptor;
242
+ /**
243
+ * Type predicate for the `'dom'` discriminator. Use to narrow a
244
+ * `ClipDescriptor` to `DomClipDescriptor` (which has `clipId`) without
245
+ * inline `c.kind === 'dom'` repetition.
246
+ */
247
+ declare function isDomClip(desc: ClipDescriptor): desc is DomClipDescriptor;
248
+ /**
249
+ * Public input shape for `editor.addTrack(config)`. All fields optional —
250
+ * defaults match the declarative `<daw-track>` defaults.
251
+ */
252
+ interface TrackConfig {
253
+ name?: string;
254
+ volume?: number;
255
+ pan?: number;
256
+ muted?: boolean;
257
+ soloed?: boolean;
258
+ clips?: ClipConfig[];
259
+ }
260
+ /**
261
+ * Public input shape for clips passed via `TrackConfig.clips` or
262
+ * `editor.addClip(trackId, config)`. `src` is required — every clip needs
263
+ * an audio source to load. Other fields default to the matching
264
+ * `<daw-clip>` attribute defaults.
265
+ */
266
+ interface ClipConfig {
267
+ src: string;
268
+ peaksSrc?: string;
269
+ start?: number;
270
+ duration?: number;
271
+ offset?: number;
272
+ gain?: number;
273
+ name?: string;
274
+ fadeIn?: number;
275
+ fadeOut?: number;
276
+ fadeType?: FadeType;
277
+ }
216
278
 
217
279
  /**
218
280
  * Peak generation pipeline: AudioBuffer → web worker → WaveformData → PeakData.
@@ -584,6 +646,23 @@ interface DawRecordingErrorDetail {
584
646
  trackId: string;
585
647
  error: unknown;
586
648
  }
649
+ interface DawClipConnectedDetail {
650
+ clipId: string;
651
+ element: DawClipElement;
652
+ }
653
+ interface DawClipIdDetail {
654
+ trackId: string;
655
+ clipId: string;
656
+ }
657
+ interface DawClipUpdateDetail {
658
+ trackId: string;
659
+ clipId: string;
660
+ }
661
+ interface DawClipErrorDetail {
662
+ trackId: string;
663
+ clipId: string;
664
+ error: unknown;
665
+ }
587
666
  interface DawClipMoveDetail {
588
667
  readonly trackId: string;
589
668
  readonly clipId: string;
@@ -623,6 +702,10 @@ interface DawEventMap {
623
702
  'daw-recording-start': CustomEvent<DawRecordingStartDetail>;
624
703
  'daw-recording-complete': CustomEvent<DawRecordingCompleteDetail>;
625
704
  'daw-recording-error': CustomEvent<DawRecordingErrorDetail>;
705
+ 'daw-clip-connected': CustomEvent<DawClipConnectedDetail>;
706
+ 'daw-clip-update': CustomEvent<DawClipUpdateDetail>;
707
+ 'daw-clip-ready': CustomEvent<DawClipIdDetail>;
708
+ 'daw-clip-error': CustomEvent<DawClipErrorDetail>;
626
709
  'daw-clip-move': CustomEvent<DawClipMoveDetail>;
627
710
  'daw-clip-trim': CustomEvent<DawClipTrimDetail>;
628
711
  'daw-clip-split': CustomEvent<DawClipSplitDetail>;
@@ -649,6 +732,13 @@ declare class DawEditorElement extends LitElement {
649
732
  clipHeaders: boolean;
650
733
  clipHeaderHeight: number;
651
734
  interactiveClips: boolean;
735
+ /**
736
+ * When true, the timeline fills the visible viewport even if total clip
737
+ * duration is less. Lets the ruler render before any audio is loaded —
738
+ * useful for empty editors and recording UIs. In beats mode the 32-bar
739
+ * floor already provides this; this attribute controls the temporal mode.
740
+ */
741
+ indefinitePlayback: boolean;
652
742
  scaleMode: 'temporal' | 'beats';
653
743
  get ticksPerPixel(): number;
654
744
  set ticksPerPixel(value: number);
@@ -710,10 +800,7 @@ declare class DawEditorElement extends LitElement {
710
800
  get engine(): PlaylistEngine | null;
711
801
  get renderSamplesPerPixel(): number;
712
802
  /** Re-extract peaks for a clip at new offset/duration from cached WaveformData. */
713
- reextractClipPeaks(clipId: string, offsetSamples: number, durationSamples: number): {
714
- data: Peaks[];
715
- length: number;
716
- } | null;
803
+ reextractClipPeaks(clipId: string, offsetSamples: number, durationSamples: number): PeakData | null;
717
804
  private _pointer;
718
805
  private _viewport;
719
806
  static styles: lit.CSSResult[];
@@ -748,6 +835,42 @@ declare class DawEditorElement extends LitElement {
748
835
  private static _CONTROL_PROPS;
749
836
  private _onTrackControl;
750
837
  private _onTrackRemoveRequest;
838
+ private _onClipConnected;
839
+ private _onClipUpdate;
840
+ private _onClipRemovedFromDom;
841
+ private _loadAndAppendClip;
842
+ /**
843
+ * Resolve pre-computed peaks for a clip: fetch the .dat/.json, validate the
844
+ * sample rate matches the AudioContext, return the WaveformData or null.
845
+ * Warns on fetch failure and on sample-rate mismatch — never silent.
846
+ *
847
+ * Shared between `_loadTrack` (peaks-first preview path) and
848
+ * `_loadAndAppendClip` (incremental late-append).
849
+ */
850
+ private _resolvePeaks;
851
+ /**
852
+ * Construct an AudioClip from a decoded buffer (and optional WaveformData),
853
+ * align its id with the source `<daw-clip>.clipId` when present, populate
854
+ * `_clipBuffers` / `_clipOffsets`, generate peaks via the worker pipeline,
855
+ * and populate `_peaksData`. Returns the finished AudioClip.
856
+ *
857
+ * Shared between `_loadTrack`'s standard path and `_loadAndAppendClip`.
858
+ * Not used by `_loadTrack`'s peaks-first preview path because that path
859
+ * uses sync `extractPeaks` and inserts a preview track BEFORE audio decode.
860
+ */
861
+ private _finalizeAudioClip;
862
+ /** Remove a single clip from all per-clip caches. Used by error rollbacks. */
863
+ private _purgeClipCaches;
864
+ /**
865
+ * Recompute duration and forward an updated track to the engine. Single
866
+ * source of truth for the incremental-vs-full-rebuild policy used by every
867
+ * clip-level mutation (addClip, updateClip, removeClip, _applyClipUpdate).
868
+ * Use the engine's incremental updateTrack when available; otherwise fall
869
+ * back to full setTracks (legacy adapters).
870
+ */
871
+ private _commitTrackChange;
872
+ private _applyClipUpdate;
873
+ private _removeClipFromTrack;
751
874
  private _readTrackDescriptor;
752
875
  private _loadTrack;
753
876
  _fetchAndDecode(src: string): Promise<AudioBuffer>;
@@ -760,6 +883,67 @@ declare class DawEditorElement extends LitElement {
760
883
  private _onDragLeave;
761
884
  private _onDrop;
762
885
  loadFiles(files: FileList | File[]): Promise<LoadFilesResult>;
886
+ /**
887
+ * Build the engine if it hasn't been built yet. Lets consumers obtain a
888
+ * non-null `editor.engine` before any track has been loaded — useful for
889
+ * wiring analyzers, effects, or master taps before content arrives.
890
+ */
891
+ ready(): Promise<PlaylistEngine>;
892
+ /**
893
+ * Wait for either `readyEvent` or `errorEvent` to fire on this editor for
894
+ * the entity matching `matchesId`. Listeners are wired synchronously, then
895
+ * `setup` is called (typical: appendChild). Resolves with `resolveValue`
896
+ * on ready; rejects with a normalized Error on error. Used by addTrack and
897
+ * addClip to share their Promise-with-listener-cleanup machinery.
898
+ */
899
+ private _awaitId;
900
+ /**
901
+ * Append a `<daw-track>` element built from `config` and resolve once the
902
+ * track finishes loading (or reject on `daw-track-error`). Goes through
903
+ * the same `_loadTrack` pipeline as declarative tracks, so descriptors,
904
+ * peaks, and clip buffers are populated correctly.
905
+ */
906
+ addTrack(config?: TrackConfig): Promise<DawTrackElement>;
907
+ /**
908
+ * Remove a track by id. Equivalent to `trackElement.remove()` —
909
+ * the editor's MutationObserver handles engine and cache cleanup.
910
+ * No-op if no matching track exists.
911
+ */
912
+ removeTrack(trackId: string): void;
913
+ /**
914
+ * Update reflected attributes on a track. For DOM-element tracks the changes
915
+ * are written to the `<daw-track>` element (which fires `daw-track-update`);
916
+ * for tracks without a DOM element (file drops) the descriptor and engine
917
+ * state are updated in place.
918
+ */
919
+ updateTrack(trackId: string, partial: Partial<TrackConfig>): void;
920
+ /**
921
+ * Append a clip to an existing track. Builds a `<daw-clip>` from `config`
922
+ * and appends it to the track's DOM element when one exists; resolves with
923
+ * the new clip's id once the audio decode + peak generation finish.
924
+ */
925
+ addClip(trackId: string, config: ClipConfig): Promise<string>;
926
+ /**
927
+ * Remove a clip by id. Removes the matching `<daw-clip>` DOM element when
928
+ * present (MutationObserver handles cleanup); otherwise updates engine
929
+ * state directly. No-op if no matching clip exists.
930
+ */
931
+ removeClip(trackId: string, clipId: string): void;
932
+ /**
933
+ * Update a clip's position (start/duration/offset) or properties (gain/name).
934
+ * For DOM-element clips, writes properties on the `<daw-clip>` element which
935
+ * fires `daw-clip-update`; otherwise applies directly via `_applyClipUpdate`.
936
+ *
937
+ * Re-decoding (changing `src`) is not supported via this method — remove and
938
+ * re-add the clip instead.
939
+ *
940
+ * Note: `fadeIn` / `fadeOut` / `fadeType` on the partial are written to the
941
+ * `<daw-clip>` element (so they round-trip in the descriptor), but engine-side
942
+ * fade application from `<daw-clip>` properties is not yet implemented — see
943
+ * the broader fade-engine integration tracked separately.
944
+ */
945
+ updateClip(trackId: string, clipId: string, partial: Partial<ClipConfig>): void;
946
+ private _buildClipElement;
763
947
  play(startTime?: number): Promise<void>;
764
948
  pause(): void;
765
949
  stop(): void;
@@ -965,4 +1149,4 @@ interface SplitHost {
965
1149
  */
966
1150
  declare function splitAtPlayhead(host: SplitHost): boolean;
967
1151
 
968
- export { AudioResumeController, type ClipDescriptor, type ClipEngineContract, ClipPointerHandler, type ClipPointerHost, DawClipElement, type DawClipMoveDetail, type DawClipSplitDetail, type DawClipTrimDetail, DawEditorElement, type DawErrorDetail, type DawEvent, type DawEventMap, type DawFilesLoadErrorDetail, DawGridElement, DawKeyboardShortcutsElement, DawPauseButtonElement, DawPlayButtonElement, DawPlayheadElement, DawRecordButtonElement, type DawRecordingCompleteDetail, type DawRecordingErrorDetail, type DawRecordingStartDetail, DawRulerElement, type DawSeekDetail, type DawSelectionDetail, DawSelectionElement, DawStopButtonElement, type DawTrackConnectedDetail, type DawTrackControlDetail, DawTrackControlsElement, DawTrackElement, type DawTrackErrorDetail, type DawTrackIdDetail, type DawTrackRemoveDetail, type DawTrackSelectDetail, DawTransportButton, DawTransportElement, DawWaveformElement, type KeyBinding, type LoadFilesResult, type PlaybackShortcutMap, type PointerEngineContract, RecordingController, type RecordingOptions, type RecordingSession, type SplitEngineContract, type SplitHost, type SplittingShortcutMap, type TrackDescriptor, type UndoShortcutMap, type WaveformSegment, splitAtPlayhead };
1152
+ export { AudioResumeController, type ClipConfig, type ClipDescriptor, type ClipEngineContract, ClipPointerHandler, type ClipPointerHost, type DawClipConnectedDetail, DawClipElement, type DawClipErrorDetail, type DawClipIdDetail, type DawClipMoveDetail, type DawClipSplitDetail, type DawClipTrimDetail, type DawClipUpdateDetail, DawEditorElement, type DawErrorDetail, type DawEvent, type DawEventMap, type DawFilesLoadErrorDetail, DawGridElement, DawKeyboardShortcutsElement, DawPauseButtonElement, DawPlayButtonElement, DawPlayheadElement, DawRecordButtonElement, type DawRecordingCompleteDetail, type DawRecordingErrorDetail, type DawRecordingStartDetail, DawRulerElement, type DawSeekDetail, type DawSelectionDetail, DawSelectionElement, DawStopButtonElement, type DawTrackConnectedDetail, type DawTrackControlDetail, DawTrackControlsElement, DawTrackElement, type DawTrackErrorDetail, type DawTrackIdDetail, type DawTrackRemoveDetail, type DawTrackSelectDetail, DawTransportButton, DawTransportElement, DawWaveformElement, type DomClipDescriptor, type DropClipDescriptor, type KeyBinding, type LoadFilesResult, type PlaybackShortcutMap, type PointerEngineContract, RecordingController, type RecordingOptions, type RecordingSession, type SplitEngineContract, type SplitHost, type SplittingShortcutMap, type TrackConfig, type TrackDescriptor, type UndoShortcutMap, type WaveformSegment, isDomClip, splitAtPlayhead };