@design.estate/dees-wcctools 3.8.4 → 3.9.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@design.estate/dees-wcctools",
3
- "version": "3.8.4",
3
+ "version": "3.9.0",
4
4
  "private": false,
5
5
  "description": "A set of web component tools for creating element catalogues, enabling the structured development and documentation of custom elements and pages.",
6
6
  "exports": {
@@ -20,7 +20,8 @@
20
20
  "@design.estate/dees-domtools": "^2.5.4",
21
21
  "@design.estate/dees-element": "^2.2.4",
22
22
  "@push.rocks/smartdelay": "^3.0.5",
23
- "lit": "^3.3.2"
23
+ "lit": "^3.3.2",
24
+ "mediabunny": "^1.40.1"
24
25
  },
25
26
  "devDependencies": {
26
27
  "@api.global/typedserver": "^8.4.6",
@@ -59,5 +60,11 @@
59
60
  "element testing",
60
61
  "page development"
61
62
  ],
62
- "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977"
63
+ "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977",
64
+ "pnpm": {
65
+ "overrides": {
66
+ "@types/dom-webcodecs": "./ts_web/types/dom-webcodecs-stub",
67
+ "@types/dom-mediacapture-transform": "./ts_web/types/dom-mediacapture-stub"
68
+ }
69
+ }
63
70
  }
package/readme.hints.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Project Hints and Findings
2
2
 
3
+ ## Mediabunny / @types/dom-webcodecs Override (2026-04-12)
4
+
5
+ The `mediabunny` package depends on `@types/dom-webcodecs` and `@types/dom-mediacapture-transform`, which conflict with TypeScript 6's built-in WebCodecs types in `lib.dom.d.ts`. We override both via `pnpm.overrides` in `package.json`, pointing them to local stubs in `ts_web/types/`:
6
+ - `dom-webcodecs-stub/` — empty, since TS6 provides these types natively
7
+ - `dom-mediacapture-stub/` — provides `MediaStreamVideoTrack` and `MediaStreamAudioTrack` interfaces (not yet in `lib.dom.d.ts`)
8
+
9
+ If mediabunny drops these `@types` dependencies in a future version, the overrides can be removed.
10
+
3
11
  ## TypeScript 6.0 & Build Tooling (2026-04-12)
4
12
 
5
13
  ### TypeScript 6.0 Strict Defaults
package/readme.md CHANGED
@@ -10,7 +10,7 @@
10
10
  - 🔧 **Real-time Property Editing** — Modify component props on the fly with auto-detected editors
11
11
  - 🌓 **Theme Switching** — Test light/dark modes instantly
12
12
  - 📱 **Responsive Viewport Testing** — Phone, phablet, tablet, and desktop views
13
- - 🎬 **Screen Recording** — Record component demos with audio support and video trimming
13
+ - 🎬 **Screen Recording** — Record component demos with audio, trimming, and MP4/WebM export
14
14
  - 🧪 **Advanced Demo Tools** — Post-render hooks for interactive testing
15
15
  - 📂 **Section-based Organization** — Group components into custom sections with filtering and sorting
16
16
  - 🚀 **Zero-config Setup** — TypeScript and Lit support out of the box
@@ -235,15 +235,17 @@ public static styles = [
235
235
 
236
236
  ### 🎬 Screen Recording
237
237
 
238
- Record component demos directly from the catalogue:
238
+ Record component demos directly from the catalogue with full export control:
239
239
 
240
240
  - **Viewport Recording** — Record just the component viewport
241
241
  - **Full Screen Recording** — Capture the entire screen
242
242
  - **Audio Support** — Add microphone commentary with live level monitoring
243
- - **Video Trimming** — Trim start/end before export with visual timeline
244
- - **WebM Export** — High-quality video output
243
+ - **Video Trimming** — Trim start/end before export with a visual timeline
244
+ - **60fps Capture** — Smooth, high-bitrate recording at up to 60 frames per second
245
+ - **MP4 Export** — Universal H.264/AAC format via [mediabunny](https://mediabunny.dev) WebCodecs conversion (plays everywhere: WhatsApp, iMessage, Slack, etc.)
246
+ - **WebM Export** — Native VP9 output for maximum quality
245
247
 
246
- Click the red record button in the bottom toolbar to start.
248
+ Click the red record button in the bottom toolbar, choose your format (MP4 or WebM), and start recording.
247
249
 
248
250
  ### 🧪 Demo Tools
249
251
 
@@ -438,7 +440,7 @@ The wrapper provides full DOM API access:
438
440
  For custom recording integrations:
439
441
 
440
442
  ```typescript
441
- import { RecorderService } from '@design.estate/dees-wcctools';
443
+ import { RecorderService, type TOutputFormat } from '@design.estate/dees-wcctools';
442
444
 
443
445
  const recorder = new RecorderService({
444
446
  onDurationUpdate: (duration) => console.log(`${duration}s`),
@@ -446,9 +448,13 @@ const recorder = new RecorderService({
446
448
  onAudioLevelUpdate: (level) => console.log(`Audio: ${level}%`),
447
449
  });
448
450
 
451
+ // Record (always captures as WebM internally)
449
452
  await recorder.startRecording({ mode: 'viewport' });
450
453
  // ... later
451
454
  recorder.stopRecording();
455
+
456
+ // Convert to MP4 for universal playback (H.264 + AAC via WebCodecs)
457
+ const mp4Blob = await recorder.convertToMp4(recorder.recordedBlob);
452
458
  ```
453
459
 
454
460
  ## Project Structure
@@ -481,7 +487,7 @@ my-component-library/
481
487
 
482
488
  ## License and Legal Information
483
489
 
484
- This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license](./license) file.
490
+ This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
485
491
 
486
492
  **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
487
493
 
@@ -493,7 +499,7 @@ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark G
493
499
 
494
500
  ### Company Information
495
501
 
496
- Task Venture Capital GmbH
502
+ Task Venture Capital GmbH
497
503
  Registered at District Court Bremen HRB 35230 HB, Germany
498
504
 
499
505
  For any legal inquiries or further information, please contact us via email at hello@task.vc.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@design.estate/dees-wcctools',
6
- version: '3.8.4',
6
+ version: '3.9.0',
7
7
  description: 'A set of web component tools for creating element catalogues, enabling the structured development and documentation of custom elements and pages.'
8
8
  }
@@ -1,5 +1,5 @@
1
1
  import { DeesElement, customElement, html, css, property, state, type TemplateResult } from '@design.estate/dees-element';
2
- import { RecorderService } from '../services/recorder.service.js';
2
+ import { RecorderService, type TOutputFormat } from '../services/recorder.service.js';
3
3
  import type { WccDashboard } from './wcc-dashboard.js';
4
4
 
5
5
  @customElement('wcc-recording-panel')
@@ -16,6 +16,9 @@ export class WccRecordingPanel extends DeesElement {
16
16
  @state()
17
17
  accessor recordingMode: 'viewport' | 'screen' = 'viewport';
18
18
 
19
+ @state()
20
+ accessor outputFormat: TOutputFormat = 'mp4';
21
+
19
22
  @state()
20
23
  accessor audioEnabled: boolean = false;
21
24
 
@@ -380,6 +383,9 @@ export class WccRecordingPanel extends DeesElement {
380
383
  font-weight: 500;
381
384
  cursor: pointer;
382
385
  transition: all 0.15s ease;
386
+ display: inline-flex;
387
+ align-items: center;
388
+ gap: 0.5rem;
383
389
  }
384
390
 
385
391
  .preview-btn.secondary {
@@ -546,7 +552,7 @@ export class WccRecordingPanel extends DeesElement {
546
552
  border-radius: 50%;
547
553
  border-top-color: white;
548
554
  animation: spin 0.8s linear infinite;
549
- margin-right: 0.5rem;
555
+ flex-shrink: 0;
550
556
  }
551
557
 
552
558
  @keyframes spin {
@@ -591,6 +597,24 @@ export class WccRecordingPanel extends DeesElement {
591
597
  </div>
592
598
  </div>
593
599
 
600
+ <div class="recording-option-group">
601
+ <div class="recording-option-label">Format</div>
602
+ <div class="recording-mode-buttons">
603
+ <button
604
+ class="recording-mode-btn ${this.outputFormat === 'mp4' ? 'selected' : ''}"
605
+ @click=${() => this.outputFormat = 'mp4'}
606
+ >
607
+ MP4 (H.264)
608
+ </button>
609
+ <button
610
+ class="recording-mode-btn ${this.outputFormat === 'webm' ? 'selected' : ''}"
611
+ @click=${() => this.outputFormat = 'webm'}
612
+ >
613
+ WebM (VP9)
614
+ </button>
615
+ </div>
616
+ </div>
617
+
594
618
  <div class="recording-option-group">
595
619
  <div class="recording-option-label">Audio</div>
596
620
  <div class="audio-toggle">
@@ -716,7 +740,9 @@ export class WccRecordingPanel extends DeesElement {
716
740
  ?disabled=${this.isExporting}
717
741
  @click=${() => this.downloadRecording()}
718
742
  >
719
- ${this.isExporting ? html`<span class="export-spinner"></span>Exporting...` : 'Download WebM'}
743
+ ${this.isExporting
744
+ ? html`<span class="export-spinner"></span>${this.outputFormat === 'mp4' ? 'Converting to MP4...' : 'Exporting...'}`
745
+ : `Download ${this.outputFormat === 'mp4' ? 'MP4' : 'WebM'}`}
720
746
  </button>
721
747
  </div>
722
748
  </div>
@@ -764,7 +790,7 @@ export class WccRecordingPanel extends DeesElement {
764
790
  await this.recorderService.startRecording({
765
791
  mode: this.recordingMode,
766
792
  audioDeviceId: this.audioEnabled ? this.selectedMicrophoneId : undefined,
767
- viewportElement
793
+ viewportElement,
768
794
  });
769
795
 
770
796
  this.panelState = 'recording';
@@ -817,7 +843,7 @@ export class WccRecordingPanel extends DeesElement {
817
843
  try {
818
844
  let blobToDownload: Blob;
819
845
 
820
- // Handle trimming if needed
846
+ // Handle trimming if needed — always produces WebM
821
847
  const needsTrim = this.trimStart > 0.1 || this.trimEnd < this.videoDuration - 0.1;
822
848
 
823
849
  if (needsTrim) {
@@ -831,9 +857,15 @@ export class WccRecordingPanel extends DeesElement {
831
857
  blobToDownload = recordedBlob;
832
858
  }
833
859
 
860
+ // Convert WebM → MP4 if MP4 format selected
861
+ if (this.outputFormat === 'mp4') {
862
+ blobToDownload = await this.recorderService.convertToMp4(blobToDownload);
863
+ }
864
+
834
865
  // Trigger download
835
866
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
836
- const filename = `wcctools-recording-${timestamp}.webm`;
867
+ const ext = this.outputFormat === 'mp4' ? 'mp4' : 'webm';
868
+ const filename = `wcctools-recording-${timestamp}.${ext}`;
837
869
 
838
870
  const url = URL.createObjectURL(blobToDownload);
839
871
  const a = document.createElement('a');
package/ts_web/index.ts CHANGED
@@ -4,7 +4,7 @@ import type { TTemplateFactory } from './elements/wcctools.helpers.js';
4
4
  import type { IWccConfig, IWccSection } from './wcctools.interfaces.js';
5
5
 
6
6
  // Export recording components and service
7
- export { RecorderService, type IRecorderEvents, type IRecordingOptions } from './services/recorder.service.js';
7
+ export { RecorderService, type IRecorderEvents, type IRecordingOptions, type TOutputFormat } from './services/recorder.service.js';
8
8
  export { WccRecordButton } from './elements/wcc-record-button.js';
9
9
  export { WccRecordingPanel } from './elements/wcc-recording-panel.js';
10
10
 
package/ts_web/readme.md CHANGED
@@ -71,11 +71,12 @@ setupWccTools({
71
71
 
72
72
  | Export | Description |
73
73
  |--------|-------------|
74
- | `RecorderService` | Service class for screen/viewport recording |
74
+ | `RecorderService` | Service class for screen/viewport recording and MP4 conversion |
75
75
  | `WccRecordButton` | Record button UI component |
76
76
  | `WccRecordingPanel` | Recording options and preview panel |
77
77
  | `IRecorderEvents` | TypeScript interface for recorder callbacks |
78
78
  | `IRecordingOptions` | TypeScript interface for recording options |
79
+ | `TOutputFormat` | Type for output format selection (`'webm' \| 'mp4'`) |
79
80
 
80
81
  ## Section Configuration
81
82
 
@@ -96,15 +97,15 @@ The module includes these internal web components:
96
97
  | Component | Description |
97
98
  |-----------|-------------|
98
99
  | `wcc-dashboard` | Main dashboard container with routing |
99
- | `wcc-sidebar` | Navigation sidebar with collapsible sections |
100
+ | `wcc-sidebar` | Navigation sidebar with collapsible sections and search |
100
101
  | `wcc-frame` | Responsive viewport with size controls |
101
102
  | `wcc-properties` | Property panel with live editing |
102
103
  | `wcc-record-button` | Recording state indicator button |
103
- | `wcc-recording-panel` | Recording workflow UI |
104
+ | `wcc-recording-panel` | Recording workflow UI with format selection |
104
105
 
105
106
  ## RecorderService API
106
107
 
107
- For programmatic recording control:
108
+ For programmatic recording and MP4 conversion:
108
109
 
109
110
  ```typescript
110
111
  import { RecorderService, type IRecorderEvents } from '@design.estate/dees-wcctools';
@@ -125,7 +126,7 @@ const mics = await recorder.loadMicrophones(true);
125
126
  // Start audio level monitoring
126
127
  await recorder.startAudioMonitoring(mics[0].deviceId);
127
128
 
128
- // Start recording
129
+ // Start recording (always captures as WebM internally at up to 60fps)
129
130
  await recorder.startRecording({
130
131
  mode: 'viewport',
131
132
  audioDeviceId: mics[0].deviceId,
@@ -135,7 +136,10 @@ await recorder.startRecording({
135
136
  // Stop recording
136
137
  recorder.stopRecording();
137
138
 
138
- // Export trimmed video
139
+ // Convert to MP4 for universal playback (H.264 + AAC via WebCodecs)
140
+ const mp4Blob = await recorder.convertToMp4(recorder.recordedBlob);
141
+
142
+ // Or export trimmed video
139
143
  const trimmedBlob = await recorder.exportTrimmedVideo(videoElement, startTime, endTime);
140
144
 
141
145
  // Cleanup
@@ -148,6 +152,9 @@ recorder.dispose();
148
152
  ts_web/
149
153
  ├── index.ts # Main exports
150
154
  ├── wcctools.interfaces.ts # Type definitions
155
+ ├── types/
156
+ │ ├── dom-webcodecs-stub/ # TS6 compatibility shim
157
+ │ └── dom-mediacapture-stub/ # MediaCapture Transform types
151
158
  ├── elements/
152
159
  │ ├── wcc-dashboard.ts # Root dashboard component
153
160
  │ ├── wcc-sidebar.ts # Navigation sidebar
@@ -157,7 +164,7 @@ ts_web/
157
164
  │ ├── wcc-recording-panel.ts # Recording options/preview
158
165
  │ └── wcctools.helpers.ts # Shared utilities
159
166
  ├── services/
160
- │ └── recorder.service.ts # MediaRecorder abstraction
167
+ │ └── recorder.service.ts # MediaRecorder + mediabunny MP4 conversion
161
168
  └── pages/
162
169
  └── index.ts # Built-in pages
163
170
  ```
@@ -165,9 +172,9 @@ ts_web/
165
172
  ## Features
166
173
 
167
174
  - 🎨 Interactive component preview
168
- - 📂 Section-based sidebar with filtering & sorting
175
+ - 📂 Section-based sidebar with filtering, sorting & search (by name, tag, or group)
169
176
  - 🔧 Real-time property editing with type detection
170
177
  - 🌓 Theme switching (light/dark)
171
178
  - 📱 Responsive viewport testing
172
- - 🎬 Screen recording with trimming
179
+ - 🎬 Screen recording with MP4/WebM export, trimming, and audio
173
180
  - 🔗 URL-based deep linking
@@ -1,7 +1,11 @@
1
1
  /**
2
- * RecorderService - Handles all MediaRecorder, audio monitoring, and video export logic
2
+ * RecorderService - Handles all MediaRecorder, audio monitoring, and video export logic.
3
+ * Recording always uses MediaRecorder → WebM (the reliable browser path).
4
+ * MP4 output is produced by converting WebM → MP4 via mediabunny at export time.
3
5
  */
4
6
 
7
+ export type TOutputFormat = 'webm' | 'mp4';
8
+
5
9
  export interface IRecorderEvents {
6
10
  onDurationUpdate?: (duration: number) => void;
7
11
  onRecordingComplete?: (blob: Blob) => void;
@@ -14,6 +18,7 @@ export interface IRecordingOptions {
14
18
  mode: 'viewport' | 'screen';
15
19
  audioDeviceId?: string;
16
20
  viewportElement?: HTMLElement;
21
+ outputFormat?: TOutputFormat;
17
22
  }
18
23
 
19
24
  export class RecorderService {
@@ -24,6 +29,7 @@ export class RecorderService {
24
29
  private _duration: number = 0;
25
30
  private _recordedBlob: Blob | null = null;
26
31
  private _isRecording: boolean = false;
32
+ private _outputFormat: TOutputFormat = 'webm';
27
33
 
28
34
  // Audio monitoring state
29
35
  private audioContext: AudioContext | null = null;
@@ -56,6 +62,10 @@ export class RecorderService {
56
62
  return this._recordedBlob;
57
63
  }
58
64
 
65
+ get outputFormat(): TOutputFormat {
66
+ return this._outputFormat;
67
+ }
68
+
59
69
  // Update event callbacks
60
70
  setEvents(events: IRecorderEvents): void {
61
71
  this.events = { ...this.events, ...events };
@@ -132,13 +142,16 @@ export class RecorderService {
132
142
 
133
143
  async startRecording(options: IRecordingOptions): Promise<void> {
134
144
  try {
145
+ this._outputFormat = options.outputFormat || 'webm';
146
+
135
147
  // Stop audio monitoring before recording
136
148
  this.stopAudioMonitoring();
137
149
 
138
150
  // Get video stream based on mode
139
151
  const displayMediaOptions: DisplayMediaStreamOptions = {
140
152
  video: {
141
- displaySurface: options.mode === 'viewport' ? 'browser' : 'monitor'
153
+ displaySurface: options.mode === 'viewport' ? 'browser' : 'monitor',
154
+ frameRate: { ideal: 60 },
142
155
  } as MediaTrackConstraints,
143
156
  audio: false
144
157
  };
@@ -182,12 +195,23 @@ export class RecorderService {
182
195
  // Store stream for cleanup
183
196
  this.currentStream = combinedStream;
184
197
 
185
- // Create MediaRecorder
198
+ // Handle stream ending (user clicks "Stop sharing")
199
+ videoStream.getVideoTracks()[0].onended = () => {
200
+ if (this._isRecording) {
201
+ this.stopRecording();
202
+ this.events.onStreamEnded?.();
203
+ }
204
+ };
205
+
206
+ // Always record as WebM — conversion to MP4 happens at export time
186
207
  const mimeType = MediaRecorder.isTypeSupported('video/webm;codecs=vp9')
187
208
  ? 'video/webm;codecs=vp9'
188
209
  : 'video/webm';
189
210
 
190
- this.mediaRecorder = new MediaRecorder(combinedStream, { mimeType });
211
+ this.mediaRecorder = new MediaRecorder(combinedStream, {
212
+ mimeType,
213
+ videoBitsPerSecond: 8_000_000, // 8 Mbps for smooth, high-quality capture
214
+ });
191
215
  this.recordedChunks = [];
192
216
 
193
217
  this.mediaRecorder.ondataavailable = (e) => {
@@ -198,14 +222,6 @@ export class RecorderService {
198
222
 
199
223
  this.mediaRecorder.onstop = () => this.handleRecordingComplete();
200
224
 
201
- // Handle stream ending (user clicks "Stop sharing")
202
- videoStream.getVideoTracks()[0].onended = () => {
203
- if (this._isRecording) {
204
- this.stopRecording();
205
- this.events.onStreamEnded?.();
206
- }
207
- };
208
-
209
225
  this.mediaRecorder.start(1000); // Capture in 1-second chunks
210
226
 
211
227
  // Start duration timer
@@ -236,9 +252,7 @@ export class RecorderService {
236
252
  }
237
253
 
238
254
  private async handleRecordingComplete(): Promise<void> {
239
- // Create blob from recorded chunks
240
255
  const blob = new Blob(this.recordedChunks, { type: 'video/webm' });
241
-
242
256
  this._recordedBlob = blob;
243
257
 
244
258
  // Stop all tracks
@@ -251,7 +265,51 @@ export class RecorderService {
251
265
  this.events.onRecordingComplete?.(this._recordedBlob);
252
266
  }
253
267
 
254
- // ==================== Trim & Export ====================
268
+ // ==================== Conversion & Export ====================
269
+
270
+ /**
271
+ * Converts a WebM blob to MP4 using mediabunny's Conversion API.
272
+ * Uses WebCodecs for hardware-accelerated H.264 encoding.
273
+ */
274
+ async convertToMp4(webmBlob: Blob): Promise<Blob> {
275
+ const {
276
+ Input, Output, Conversion, BlobSource, BufferTarget, Mp4OutputFormat, WEBM, QUALITY_HIGH,
277
+ } = await import('mediabunny');
278
+
279
+ const input = new Input({
280
+ source: new BlobSource(webmBlob),
281
+ formats: [WEBM],
282
+ });
283
+
284
+ const target = new BufferTarget();
285
+ const output = new Output({
286
+ format: new Mp4OutputFormat({ fastStart: 'in-memory' }),
287
+ target,
288
+ });
289
+
290
+ const conversion = await Conversion.init({
291
+ input,
292
+ output,
293
+ // Force transcoding from VP9 → H.264 and Opus → AAC
294
+ video: {
295
+ codec: 'avc',
296
+ bitrate: QUALITY_HIGH,
297
+ fit: 'contain',
298
+ },
299
+ audio: {
300
+ codec: 'aac',
301
+ bitrate: QUALITY_HIGH,
302
+ },
303
+ });
304
+ await conversion.execute();
305
+
306
+ const buffer = target.buffer;
307
+ if (!buffer || buffer.byteLength === 0) {
308
+ throw new Error('MP4 conversion produced empty output');
309
+ }
310
+
311
+ return new Blob([buffer], { type: 'video/mp4' });
312
+ }
255
313
 
256
314
  async exportTrimmedVideo(
257
315
  videoElement: HTMLVideoElement,
@@ -0,0 +1,12 @@
1
+ // Minimal type stubs for MediaCapture Transform API types not yet in lib.dom.d.ts.
2
+ // These specialize MediaStreamTrack for audio/video so mediabunny's API is type-safe.
3
+
4
+ interface MediaStreamAudioTrack extends MediaStreamTrack {
5
+ readonly kind: 'audio';
6
+ clone(): MediaStreamAudioTrack;
7
+ }
8
+
9
+ interface MediaStreamVideoTrack extends MediaStreamTrack {
10
+ readonly kind: 'video';
11
+ clone(): MediaStreamVideoTrack;
12
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "@types/dom-mediacapture-transform",
3
+ "version": "0.0.0",
4
+ "description": "Minimal stub providing MediaStreamVideoTrack/MediaStreamAudioTrack for TS 6",
5
+ "types": "index.d.ts"
6
+ }
@@ -0,0 +1,2 @@
1
+ // Empty stub: TypeScript 6 includes WebCodecs types in lib.dom.d.ts natively.
2
+ // This prevents @types/dom-webcodecs from conflicting with the built-in types.
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "@types/dom-webcodecs",
3
+ "version": "0.0.0",
4
+ "description": "Empty stub — TypeScript 6 provides WebCodecs types natively in lib.dom.d.ts",
5
+ "types": "index.d.ts"
6
+ }