@dawcore/components 0.0.18 → 0.0.19
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 +44 -1
- package/dist/index.d.ts +44 -1
- package/dist/index.js +118 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +118 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -4
package/dist/index.mjs
CHANGED
|
@@ -3446,6 +3446,108 @@ async function loadFiles(host, files) {
|
|
|
3446
3446
|
return { loaded, failed };
|
|
3447
3447
|
}
|
|
3448
3448
|
|
|
3449
|
+
// src/interactions/midi-loader.ts
|
|
3450
|
+
var INSTALL_HINT = "@dawcore/midi is required for loadMidi(). Install with: npm install @dawcore/midi";
|
|
3451
|
+
async function loadMidiImpl(host, source, options = {}) {
|
|
3452
|
+
const startTime = options.startTime ?? 0;
|
|
3453
|
+
if (!Number.isFinite(startTime) || startTime < 0) {
|
|
3454
|
+
throw new RangeError(
|
|
3455
|
+
"loadMidi: startTime must be a non-negative finite number (got " + String(options.startTime) + ")"
|
|
3456
|
+
);
|
|
3457
|
+
}
|
|
3458
|
+
let midiModule;
|
|
3459
|
+
try {
|
|
3460
|
+
midiModule = await import("@dawcore/midi");
|
|
3461
|
+
} catch (originalErr) {
|
|
3462
|
+
console.warn("[dawcore] @dawcore/midi dynamic import failed: " + String(originalErr));
|
|
3463
|
+
throw new Error(INSTALL_HINT);
|
|
3464
|
+
}
|
|
3465
|
+
const { parseMidiUrl, parseMidiFile } = midiModule;
|
|
3466
|
+
let parsed;
|
|
3467
|
+
if (typeof source === "string") {
|
|
3468
|
+
parsed = await parseMidiUrl(source, void 0, options.signal);
|
|
3469
|
+
} else {
|
|
3470
|
+
let buffer;
|
|
3471
|
+
try {
|
|
3472
|
+
buffer = await source.arrayBuffer();
|
|
3473
|
+
} catch (err) {
|
|
3474
|
+
throw new Error(
|
|
3475
|
+
'loadMidi: failed to read File "' + source.name + '" (' + source.size + " bytes): " + String(err)
|
|
3476
|
+
);
|
|
3477
|
+
}
|
|
3478
|
+
parsed = parseMidiFile(buffer);
|
|
3479
|
+
}
|
|
3480
|
+
const childrenBefore = new Set(host.querySelectorAll("daw-track"));
|
|
3481
|
+
const settlements = await Promise.allSettled(
|
|
3482
|
+
parsed.tracks.map(
|
|
3483
|
+
(t) => host.addTrack({
|
|
3484
|
+
name: t.name,
|
|
3485
|
+
renderMode: "piano-roll",
|
|
3486
|
+
clips: [
|
|
3487
|
+
{
|
|
3488
|
+
midiNotes: t.notes,
|
|
3489
|
+
midiChannel: t.channel,
|
|
3490
|
+
midiProgram: t.programNumber,
|
|
3491
|
+
start: startTime
|
|
3492
|
+
}
|
|
3493
|
+
]
|
|
3494
|
+
})
|
|
3495
|
+
)
|
|
3496
|
+
);
|
|
3497
|
+
const succeeded = [];
|
|
3498
|
+
const rejections = [];
|
|
3499
|
+
for (const s of settlements) {
|
|
3500
|
+
if (s.status === "fulfilled") {
|
|
3501
|
+
succeeded.push(s.value);
|
|
3502
|
+
} else {
|
|
3503
|
+
rejections.push(s.reason);
|
|
3504
|
+
}
|
|
3505
|
+
}
|
|
3506
|
+
if (rejections.length > 0) {
|
|
3507
|
+
const appendedTracks = Array.from(host.querySelectorAll("daw-track")).filter(
|
|
3508
|
+
(el) => !childrenBefore.has(el)
|
|
3509
|
+
);
|
|
3510
|
+
for (const el of appendedTracks) {
|
|
3511
|
+
try {
|
|
3512
|
+
el.remove();
|
|
3513
|
+
} catch (cleanupErr) {
|
|
3514
|
+
console.warn("[dawcore] loadMidi cleanup failed for a track: " + String(cleanupErr));
|
|
3515
|
+
}
|
|
3516
|
+
}
|
|
3517
|
+
await Promise.resolve();
|
|
3518
|
+
for (let i = 1; i < rejections.length; i++) {
|
|
3519
|
+
console.warn(
|
|
3520
|
+
"[dawcore] loadMidi: additional track failure (" + i + "): " + stringifyReason(rejections[i])
|
|
3521
|
+
);
|
|
3522
|
+
}
|
|
3523
|
+
const first = rejections[0];
|
|
3524
|
+
if (rejections.length > 1) {
|
|
3525
|
+
const message = "loadMidi: " + rejections.length + " of " + settlements.length + " tracks failed; first: " + (first instanceof Error ? first.message : stringifyReason(first));
|
|
3526
|
+
throw new Error(message);
|
|
3527
|
+
}
|
|
3528
|
+
throw first instanceof Error ? first : new Error(stringifyReason(first));
|
|
3529
|
+
}
|
|
3530
|
+
return {
|
|
3531
|
+
trackIds: succeeded.map((el) => el.trackId),
|
|
3532
|
+
bpm: parsed.bpm,
|
|
3533
|
+
timeSignature: parsed.timeSignature,
|
|
3534
|
+
duration: parsed.duration,
|
|
3535
|
+
name: parsed.name
|
|
3536
|
+
};
|
|
3537
|
+
}
|
|
3538
|
+
function stringifyReason(reason) {
|
|
3539
|
+
if (reason === null) return "null";
|
|
3540
|
+
if (reason === void 0) return "undefined";
|
|
3541
|
+
if (typeof reason === "object") {
|
|
3542
|
+
try {
|
|
3543
|
+
return JSON.stringify(reason);
|
|
3544
|
+
} catch {
|
|
3545
|
+
return Object.prototype.toString.call(reason);
|
|
3546
|
+
}
|
|
3547
|
+
}
|
|
3548
|
+
return String(reason);
|
|
3549
|
+
}
|
|
3550
|
+
|
|
3449
3551
|
// src/interactions/recording-clip.ts
|
|
3450
3552
|
import { createClip as createClip2 } from "@waveform-playlist/core";
|
|
3451
3553
|
function addRecordedClip(host, trackId, buf, startSample, durSamples, offsetSamples = 0) {
|
|
@@ -5017,6 +5119,22 @@ var DawEditorElement = class extends LitElement10 {
|
|
|
5017
5119
|
async loadFiles(files) {
|
|
5018
5120
|
return loadFiles(this, files);
|
|
5019
5121
|
}
|
|
5122
|
+
/**
|
|
5123
|
+
* Imperatively load a `.mid` file (URL or File) and create N `<daw-track>`
|
|
5124
|
+
* elements — one per note-bearing MIDI track. On any per-track failure,
|
|
5125
|
+
* every `<daw-track>` appended during the call is removed (both successful
|
|
5126
|
+
* and failed) so the editor returns to its pre-call state.
|
|
5127
|
+
*
|
|
5128
|
+
* `options.signal` is forwarded to `fetch()` only for URL sources; aborting
|
|
5129
|
+
* after parsing does not cancel in-flight `addTrack` calls.
|
|
5130
|
+
*
|
|
5131
|
+
* Requires the optional `@dawcore/midi` peer dep — throws with an install
|
|
5132
|
+
* hint (and `console.warn`s the original error) when the dynamic import
|
|
5133
|
+
* fails for any reason.
|
|
5134
|
+
*/
|
|
5135
|
+
async loadMidi(source, options) {
|
|
5136
|
+
return loadMidiImpl(this, source, options);
|
|
5137
|
+
}
|
|
5020
5138
|
// --- Programmatic Track API ---
|
|
5021
5139
|
/**
|
|
5022
5140
|
* Build the engine if it hasn't been built yet. Lets consumers obtain a
|