@beatbax/engine 0.1.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/dist/.tsbuildinfo +1 -0
- package/dist/audio/bufferedRenderer.d.ts +32 -0
- package/dist/audio/bufferedRenderer.d.ts.map +1 -0
- package/dist/audio/bufferedRenderer.js +309 -0
- package/dist/audio/bufferedRenderer.js.map +1 -0
- package/dist/audio/pcmRenderer.d.ts +25 -0
- package/dist/audio/pcmRenderer.d.ts.map +1 -0
- package/dist/audio/pcmRenderer.js +1288 -0
- package/dist/audio/pcmRenderer.js.map +1 -0
- package/dist/audio/playback.d.ts +57 -0
- package/dist/audio/playback.d.ts.map +1 -0
- package/dist/audio/playback.js +794 -0
- package/dist/audio/playback.js.map +1 -0
- package/dist/chips/gameboy/apu.d.ts +9 -0
- package/dist/chips/gameboy/apu.d.ts.map +1 -0
- package/dist/chips/gameboy/apu.js +27 -0
- package/dist/chips/gameboy/apu.js.map +1 -0
- package/dist/chips/gameboy/noise.d.ts +6 -0
- package/dist/chips/gameboy/noise.d.ts.map +1 -0
- package/dist/chips/gameboy/noise.js +155 -0
- package/dist/chips/gameboy/noise.js.map +1 -0
- package/dist/chips/gameboy/packet.d.ts +3 -0
- package/dist/chips/gameboy/packet.d.ts.map +1 -0
- package/dist/chips/gameboy/packet.js +3 -0
- package/dist/chips/gameboy/packet.js.map +1 -0
- package/dist/chips/gameboy/periodTables.d.ts +16 -0
- package/dist/chips/gameboy/periodTables.d.ts.map +1 -0
- package/dist/chips/gameboy/periodTables.js +29 -0
- package/dist/chips/gameboy/periodTables.js.map +1 -0
- package/dist/chips/gameboy/pulse.d.ts +12 -0
- package/dist/chips/gameboy/pulse.d.ts.map +1 -0
- package/dist/chips/gameboy/pulse.js +275 -0
- package/dist/chips/gameboy/pulse.js.map +1 -0
- package/dist/chips/gameboy/wave.d.ts +8 -0
- package/dist/chips/gameboy/wave.d.ts.map +1 -0
- package/dist/chips/gameboy/wave.js +146 -0
- package/dist/chips/gameboy/wave.js.map +1 -0
- package/dist/effects/index.d.ts +7 -0
- package/dist/effects/index.d.ts.map +1 -0
- package/dist/effects/index.js +1028 -0
- package/dist/effects/index.js.map +1 -0
- package/dist/effects/types.d.ts +8 -0
- package/dist/effects/types.d.ts.map +1 -0
- package/dist/effects/types.js +2 -0
- package/dist/effects/types.js.map +1 -0
- package/dist/expand/refExpander.d.ts +14 -0
- package/dist/expand/refExpander.d.ts.map +1 -0
- package/dist/expand/refExpander.js +130 -0
- package/dist/expand/refExpander.js.map +1 -0
- package/dist/export/index.d.ts +5 -0
- package/dist/export/index.d.ts.map +1 -0
- package/dist/export/index.js +5 -0
- package/dist/export/index.js.map +1 -0
- package/dist/export/jsonExport.d.ts +9 -0
- package/dist/export/jsonExport.d.ts.map +1 -0
- package/dist/export/jsonExport.js +184 -0
- package/dist/export/jsonExport.js.map +1 -0
- package/dist/export/midiExport.d.ts +9 -0
- package/dist/export/midiExport.d.ts.map +1 -0
- package/dist/export/midiExport.js +390 -0
- package/dist/export/midiExport.js.map +1 -0
- package/dist/export/ugeWriter.d.ts +33 -0
- package/dist/export/ugeWriter.d.ts.map +1 -0
- package/dist/export/ugeWriter.js +1997 -0
- package/dist/export/ugeWriter.js.map +1 -0
- package/dist/export/wavWriter.d.ts +24 -0
- package/dist/export/wavWriter.d.ts.map +1 -0
- package/dist/export/wavWriter.js +126 -0
- package/dist/export/wavWriter.js.map +1 -0
- package/dist/import/index.d.ts +5 -0
- package/dist/import/index.d.ts.map +1 -0
- package/dist/import/index.js +8 -0
- package/dist/import/index.js.map +1 -0
- package/dist/import/remoteCache.d.ts +60 -0
- package/dist/import/remoteCache.d.ts.map +1 -0
- package/dist/import/remoteCache.js +194 -0
- package/dist/import/remoteCache.js.map +1 -0
- package/dist/import/uge/uge.reader.d.ts +27 -0
- package/dist/import/uge/uge.reader.d.ts.map +1 -0
- package/dist/import/uge/uge.reader.js +545 -0
- package/dist/import/uge/uge.reader.js.map +1 -0
- package/dist/import/urlUtils.d.ts +50 -0
- package/dist/import/urlUtils.d.ts.map +1 -0
- package/dist/import/urlUtils.js +87 -0
- package/dist/import/urlUtils.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +318 -0
- package/dist/index.js.map +1 -0
- package/dist/instruments/instrumentState.d.ts +15 -0
- package/dist/instruments/instrumentState.d.ts.map +1 -0
- package/dist/instruments/instrumentState.js +24 -0
- package/dist/instruments/instrumentState.js.map +1 -0
- package/dist/parser/ast.d.ts +22 -0
- package/dist/parser/ast.d.ts.map +1 -0
- package/dist/parser/ast.js +5 -0
- package/dist/parser/ast.js.map +1 -0
- package/dist/parser/index.d.ts +14 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +10 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/peggy/generated/parser.d.ts +8 -0
- package/dist/parser/peggy/generated/parser.d.ts.map +1 -0
- package/dist/parser/peggy/generated/parser.js +6269 -0
- package/dist/parser/peggy/generated/parser.js.map +1 -0
- package/dist/parser/peggy/index.d.ts +3 -0
- package/dist/parser/peggy/index.d.ts.map +1 -0
- package/dist/parser/peggy/index.js +555 -0
- package/dist/parser/peggy/index.js.map +1 -0
- package/dist/parser/structured.d.ts +16 -0
- package/dist/parser/structured.d.ts.map +1 -0
- package/dist/parser/structured.js +232 -0
- package/dist/parser/structured.js.map +1 -0
- package/dist/parser/tokenizer.d.ts +12 -0
- package/dist/parser/tokenizer.d.ts.map +1 -0
- package/dist/parser/tokenizer.js +14 -0
- package/dist/parser/tokenizer.js.map +1 -0
- package/dist/patterns/expand.d.ts +32 -0
- package/dist/patterns/expand.d.ts.map +1 -0
- package/dist/patterns/expand.js +184 -0
- package/dist/patterns/expand.js.map +1 -0
- package/dist/patterns/index.d.ts +2 -0
- package/dist/patterns/index.d.ts.map +1 -0
- package/dist/patterns/index.js +2 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/scheduler/index.d.ts +6 -0
- package/dist/scheduler/index.d.ts.map +1 -0
- package/dist/scheduler/index.js +9 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/tickScheduler.d.ts +27 -0
- package/dist/scheduler/tickScheduler.d.ts.map +1 -0
- package/dist/scheduler/tickScheduler.js +74 -0
- package/dist/scheduler/tickScheduler.js.map +1 -0
- package/dist/sequences/expand.d.ts +14 -0
- package/dist/sequences/expand.d.ts.map +1 -0
- package/dist/sequences/expand.js +137 -0
- package/dist/sequences/expand.js.map +1 -0
- package/dist/song/importResolver.browser.d.ts +29 -0
- package/dist/song/importResolver.browser.d.ts.map +1 -0
- package/dist/song/importResolver.browser.js +168 -0
- package/dist/song/importResolver.browser.js.map +1 -0
- package/dist/song/importResolver.d.ts +40 -0
- package/dist/song/importResolver.d.ts.map +1 -0
- package/dist/song/importResolver.js +445 -0
- package/dist/song/importResolver.js.map +1 -0
- package/dist/song/index.browser.d.ts +9 -0
- package/dist/song/index.browser.d.ts.map +1 -0
- package/dist/song/index.browser.js +7 -0
- package/dist/song/index.browser.js.map +1 -0
- package/dist/song/index.d.ts +8 -0
- package/dist/song/index.d.ts.map +1 -0
- package/dist/song/index.js +6 -0
- package/dist/song/index.js.map +1 -0
- package/dist/song/resolver.browser.d.ts +50 -0
- package/dist/song/resolver.browser.d.ts.map +1 -0
- package/dist/song/resolver.browser.js +536 -0
- package/dist/song/resolver.browser.js.map +1 -0
- package/dist/song/resolver.d.ts +20 -0
- package/dist/song/resolver.d.ts.map +1 -0
- package/dist/song/resolver.js +540 -0
- package/dist/song/resolver.js.map +1 -0
- package/dist/song/songModel.d.ts +34 -0
- package/dist/song/songModel.d.ts.map +1 -0
- package/dist/song/songModel.js +2 -0
- package/dist/song/songModel.js.map +1 -0
- package/dist/tests/refExpander.test.d.ts +2 -0
- package/dist/tests/refExpander.test.d.ts.map +1 -0
- package/dist/tests/refExpander.test.js +37 -0
- package/dist/tests/refExpander.test.js.map +1 -0
- package/dist/util/diag.d.ts +16 -0
- package/dist/util/diag.d.ts.map +1 -0
- package/dist/util/diag.js +29 -0
- package/dist/util/diag.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { error } from '../util/diag.js';
|
|
2
|
+
export class TickScheduler {
|
|
3
|
+
ctx;
|
|
4
|
+
lookahead;
|
|
5
|
+
interval;
|
|
6
|
+
timer = null;
|
|
7
|
+
rafId = null;
|
|
8
|
+
queue = [];
|
|
9
|
+
opts;
|
|
10
|
+
constructor(ctx, opts = {}) {
|
|
11
|
+
this.ctx = ctx;
|
|
12
|
+
this.opts = opts;
|
|
13
|
+
this.lookahead = typeof opts.lookahead === 'number' ? opts.lookahead : 0.1;
|
|
14
|
+
this.interval = typeof opts.interval === 'number' ? opts.interval : 25;
|
|
15
|
+
}
|
|
16
|
+
schedule(time, fn) {
|
|
17
|
+
this.queue.push({ time, fn });
|
|
18
|
+
this.queue.sort((a, b) => a.time - b.time);
|
|
19
|
+
}
|
|
20
|
+
scheduleAligned(time, fn, frameHz = 512) {
|
|
21
|
+
if (!isFinite(time) || frameHz <= 0)
|
|
22
|
+
return this.schedule(time, fn);
|
|
23
|
+
const framePeriod = 1 / frameHz;
|
|
24
|
+
const aligned = Math.round(time / framePeriod) * framePeriod;
|
|
25
|
+
this.schedule(aligned, fn);
|
|
26
|
+
}
|
|
27
|
+
start() {
|
|
28
|
+
if (this.timer || this.rafId)
|
|
29
|
+
return;
|
|
30
|
+
const useRaf = !!this.opts.useRaf;
|
|
31
|
+
const rafFn = this.opts.raf || (typeof globalThis.requestAnimationFrame === 'function' ? globalThis.requestAnimationFrame.bind(globalThis) : null);
|
|
32
|
+
if (useRaf && rafFn) {
|
|
33
|
+
const loop = () => {
|
|
34
|
+
this.tick();
|
|
35
|
+
this.rafId = rafFn(loop);
|
|
36
|
+
};
|
|
37
|
+
this.rafId = rafFn(loop);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const setInt = this.opts.setInterval || setInterval.bind(globalThis);
|
|
41
|
+
this.timer = setInt(() => this.tick(), this.interval);
|
|
42
|
+
}
|
|
43
|
+
stop() {
|
|
44
|
+
if (this.timer) {
|
|
45
|
+
const clearInt = this.opts.clearInterval || clearInterval.bind(globalThis);
|
|
46
|
+
clearInt(this.timer);
|
|
47
|
+
this.timer = null;
|
|
48
|
+
}
|
|
49
|
+
if (this.rafId !== null) {
|
|
50
|
+
const cancel = this.opts.cancelRaf || (typeof globalThis.cancelAnimationFrame === 'function' ? globalThis.cancelAnimationFrame.bind(globalThis) : null);
|
|
51
|
+
if (cancel)
|
|
52
|
+
cancel(this.rafId);
|
|
53
|
+
this.rafId = null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
clear() {
|
|
57
|
+
this.queue = [];
|
|
58
|
+
}
|
|
59
|
+
tick() {
|
|
60
|
+
const now = (this.ctx && typeof this.ctx.currentTime === 'number') ? this.ctx.currentTime : (Date.now() / 1000);
|
|
61
|
+
const cutoff = now + this.lookahead;
|
|
62
|
+
while (this.queue.length && this.queue[0].time <= cutoff) {
|
|
63
|
+
const ev = this.queue.shift();
|
|
64
|
+
try {
|
|
65
|
+
ev.fn();
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
error('scheduler', 'Scheduled function error: ' + (e && e.message ? e.message : String(e)));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export default TickScheduler;
|
|
74
|
+
//# sourceMappingURL=tickScheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tickScheduler.js","sourceRoot":"","sources":["../../src/scheduler/tickScheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expand sequence definitions into flat token arrays by resolving pattern
|
|
3
|
+
* references and applying sequence-level transforms (oct, rev, slow, fast,
|
|
4
|
+
* semitone transposition, and inst(name) override which is emitted as an
|
|
5
|
+
* `inst(name)` token preceding the pattern tokens).
|
|
6
|
+
*/
|
|
7
|
+
export declare function expandSequenceItems(items: string[], pats: Record<string, string[]>, insts?: Record<string, any>, _missingWarned?: Set<string>, presets?: Record<string, string>): string[];
|
|
8
|
+
export declare function expandAllSequences(seqs: Record<string, string[]>, pats: Record<string, string[]>, insts?: Record<string, any>, presets?: Record<string, string>): Record<string, string[]>;
|
|
9
|
+
declare const _default: {
|
|
10
|
+
expandSequenceItems: typeof expandSequenceItems;
|
|
11
|
+
expandAllSequences: typeof expandAllSequences;
|
|
12
|
+
};
|
|
13
|
+
export default _default;
|
|
14
|
+
//# sourceMappingURL=expand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expand.d.ts","sourceRoot":"","sources":["../../src/sequences/expand.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAoChD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,YAAY,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,CA8D3M;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAQ3M;;;;;AAED,wBAA2D"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { warn } from '../util/diag.js';
|
|
2
|
+
import { applyModsToTokens } from '../expand/refExpander.js';
|
|
3
|
+
import { materializeSequenceItems } from '../parser/structured.js';
|
|
4
|
+
/**
|
|
5
|
+
* Expand sequence definitions into flat token arrays by resolving pattern
|
|
6
|
+
* references and applying sequence-level transforms (oct, rev, slow, fast,
|
|
7
|
+
* semitone transposition, and inst(name) override which is emitted as an
|
|
8
|
+
* `inst(name)` token preceding the pattern tokens).
|
|
9
|
+
*/
|
|
10
|
+
const splitTopLevel = (s, sep = ':') => {
|
|
11
|
+
const out = [];
|
|
12
|
+
let cur = '';
|
|
13
|
+
let inS = false;
|
|
14
|
+
let inD = false;
|
|
15
|
+
let bracket = 0;
|
|
16
|
+
let paren = 0;
|
|
17
|
+
for (let i = 0; i < s.length; i++) {
|
|
18
|
+
const ch = s[i];
|
|
19
|
+
if (ch === "'" && !inD) {
|
|
20
|
+
inS = !inS;
|
|
21
|
+
cur += ch;
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (ch === '"' && !inS) {
|
|
25
|
+
inD = !inD;
|
|
26
|
+
cur += ch;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (inS || inD) {
|
|
30
|
+
cur += ch;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (ch === '[') {
|
|
34
|
+
bracket++;
|
|
35
|
+
cur += ch;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (ch === ']') {
|
|
39
|
+
if (bracket > 0)
|
|
40
|
+
bracket--;
|
|
41
|
+
cur += ch;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (ch === '(') {
|
|
45
|
+
paren++;
|
|
46
|
+
cur += ch;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (ch === ')') {
|
|
50
|
+
if (paren > 0)
|
|
51
|
+
paren--;
|
|
52
|
+
cur += ch;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (ch === sep && bracket === 0 && paren === 0) {
|
|
56
|
+
out.push(cur);
|
|
57
|
+
cur = '';
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
cur += ch;
|
|
61
|
+
}
|
|
62
|
+
out.push(cur);
|
|
63
|
+
return out.map(x => x.trim()).filter(Boolean);
|
|
64
|
+
};
|
|
65
|
+
export function expandSequenceItems(items, pats, insts, _missingWarned, presets) {
|
|
66
|
+
const out = [];
|
|
67
|
+
const missingWarned = _missingWarned || new Set();
|
|
68
|
+
// Normalize items to a string[] early so the rest of the expansion logic
|
|
69
|
+
// can operate on a consistent type. If items are structured SequenceItem
|
|
70
|
+
// objects, materialize them first.
|
|
71
|
+
let itemStrs;
|
|
72
|
+
// Ensure `items` is a non-empty array before accessing `items[0]`.
|
|
73
|
+
// Using `Array.isArray` avoids false positives for non-array objects.
|
|
74
|
+
if (Array.isArray(items) && items.length > 0 && typeof items[0] === 'object') {
|
|
75
|
+
try {
|
|
76
|
+
itemStrs = materializeSequenceItems(items);
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
itemStrs = items.map(String);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
itemStrs = items;
|
|
84
|
+
}
|
|
85
|
+
for (const it of itemStrs) {
|
|
86
|
+
if (!it || it.trim() === '')
|
|
87
|
+
continue;
|
|
88
|
+
const parts = splitTopLevel(it, ':');
|
|
89
|
+
const base = parts[0];
|
|
90
|
+
const mods = parts.slice(1);
|
|
91
|
+
// Support repetition syntax in sequence items: base may be "name*2" or a group "(A B)*2"
|
|
92
|
+
let repeat = 1;
|
|
93
|
+
const mRepBase = base.match(/^(.+?)\*(\d+)$/);
|
|
94
|
+
let realBase = base;
|
|
95
|
+
if (mRepBase) {
|
|
96
|
+
realBase = mRepBase[1];
|
|
97
|
+
repeat = parseInt(mRepBase[2], 10);
|
|
98
|
+
}
|
|
99
|
+
// If this is a parenthesized group, expand inner items recursively
|
|
100
|
+
let tokens = [];
|
|
101
|
+
const mGroup = realBase.match(/^\((.*)\)$/s);
|
|
102
|
+
if (mGroup) {
|
|
103
|
+
const inner = mGroup[1].trim();
|
|
104
|
+
const innerParts = inner.match(/[^\s]+/g) || [];
|
|
105
|
+
tokens = expandSequenceItems(innerParts, pats, insts, missingWarned);
|
|
106
|
+
}
|
|
107
|
+
else if (pats[realBase]) {
|
|
108
|
+
tokens = pats[realBase].slice();
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
tokens = [realBase];
|
|
112
|
+
// Only warn if realBase is not a known pattern AND not a known instrument
|
|
113
|
+
const isInstrument = insts && insts[realBase];
|
|
114
|
+
if (realBase && !missingWarned.has(realBase) && !isInstrument) {
|
|
115
|
+
missingWarned.add(realBase);
|
|
116
|
+
warn('sequences', `sequence item '${realBase}' referenced but no pattern named '${realBase}' was found.`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const res = applyModsToTokens(tokens, mods, presets);
|
|
120
|
+
tokens = res.tokens;
|
|
121
|
+
for (let r = 0; r < repeat; r++) {
|
|
122
|
+
out.push(...tokens);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return out;
|
|
126
|
+
}
|
|
127
|
+
export function expandAllSequences(seqs, pats, insts, presets) {
|
|
128
|
+
const res = {};
|
|
129
|
+
for (const [name, items] of Object.entries(seqs)) {
|
|
130
|
+
// items may be an array of strings or structured SequenceItem objects
|
|
131
|
+
const expanded = expandSequenceItems(items, pats, insts, undefined, presets);
|
|
132
|
+
res[name] = expanded;
|
|
133
|
+
}
|
|
134
|
+
return res;
|
|
135
|
+
}
|
|
136
|
+
export default { expandSequenceItems, expandAllSequences };
|
|
137
|
+
//# sourceMappingURL=expand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expand.js","sourceRoot":"","sources":["../../src/sequences/expand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe import resolution for .ins files.
|
|
3
|
+
* Only supports remote HTTP(S) imports - local file imports are blocked in browser contexts.
|
|
4
|
+
* This module does NOT import Node.js built-ins (fs, path) to ensure compatibility with browser bundlers.
|
|
5
|
+
*/
|
|
6
|
+
import { AST } from '../parser/ast.js';
|
|
7
|
+
import { RemoteInstrumentCache, RemoteImportOptions } from '../import/remoteCache.js';
|
|
8
|
+
export interface ImportResolverOptions {
|
|
9
|
+
/** Strict mode: treat instrument name overrides as errors instead of warnings */
|
|
10
|
+
strictMode?: boolean;
|
|
11
|
+
/** Warning handler */
|
|
12
|
+
onWarn?: (message: string, loc?: any) => void;
|
|
13
|
+
/** Remote import options (timeout, HTTPS-only, etc.) */
|
|
14
|
+
remoteOptions?: RemoteImportOptions;
|
|
15
|
+
/** Remote instrument cache (reused across multiple resolve calls) */
|
|
16
|
+
remoteCache?: RemoteInstrumentCache;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Resolve all imports in an AST and merge them into the instrument table.
|
|
20
|
+
* Returns a new AST with merged instruments.
|
|
21
|
+
* Browser version: Only supports remote imports (HTTP(S), GitHub).
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveImports(ast: AST, options?: ImportResolverOptions): Promise<AST>;
|
|
24
|
+
/**
|
|
25
|
+
* Synchronous wrapper - not supported in browser (all remote imports are async).
|
|
26
|
+
* @deprecated Not available in browser context
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveImportsSync(_ast: AST, _options?: ImportResolverOptions): AST;
|
|
29
|
+
//# sourceMappingURL=importResolver.browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importResolver.browser.d.ts","sourceRoot":"","sources":["../../src/song/importResolver.browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,GAAG,EAAW,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEtF,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sBAAsB;IACtB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC9C,wDAAwD;IACxD,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,qEAAqE;IACrE,WAAW,CAAC,EAAE,qBAAqB,CAAC;CAKrC;AA2KD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,GAAG,CAAC,CAwBd;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,GAAG,EACT,QAAQ,GAAE,qBAA0B,GACnC,GAAG,CAKL"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe import resolution for .ins files.
|
|
3
|
+
* Only supports remote HTTP(S) imports - local file imports are blocked in browser contexts.
|
|
4
|
+
* This module does NOT import Node.js built-ins (fs, path) to ensure compatibility with browser bundlers.
|
|
5
|
+
*/
|
|
6
|
+
import { isRemoteImport, isLocalImport } from '../import/urlUtils.js';
|
|
7
|
+
import { RemoteInstrumentCache } from '../import/remoteCache.js';
|
|
8
|
+
/**
|
|
9
|
+
* Validate that an AST contains only allowed node types for .ins files.
|
|
10
|
+
*/
|
|
11
|
+
function validateInsFile(ast, source) {
|
|
12
|
+
// .ins files should only contain instrument definitions and imports
|
|
13
|
+
const disallowed = [];
|
|
14
|
+
// Playback/structure directives
|
|
15
|
+
if (Object.keys(ast.pats || {}).length > 0)
|
|
16
|
+
disallowed.push('patterns');
|
|
17
|
+
if (Object.keys(ast.seqs || {}).length > 0)
|
|
18
|
+
disallowed.push('sequences');
|
|
19
|
+
if ((ast.channels || []).length > 0)
|
|
20
|
+
disallowed.push('channels');
|
|
21
|
+
if (ast.arranges && Object.keys(ast.arranges).length > 0)
|
|
22
|
+
disallowed.push('arranges');
|
|
23
|
+
if (ast.play !== undefined)
|
|
24
|
+
disallowed.push('play');
|
|
25
|
+
// Top-level scalar directives (should not be in .ins files)
|
|
26
|
+
if (ast.chip !== undefined)
|
|
27
|
+
disallowed.push('chip');
|
|
28
|
+
if (ast.bpm !== undefined)
|
|
29
|
+
disallowed.push('bpm');
|
|
30
|
+
if (ast.volume !== undefined)
|
|
31
|
+
disallowed.push('volume');
|
|
32
|
+
// Metadata
|
|
33
|
+
if (ast.metadata !== undefined && Object.keys(ast.metadata).length > 0) {
|
|
34
|
+
disallowed.push('metadata');
|
|
35
|
+
}
|
|
36
|
+
// Effect definitions
|
|
37
|
+
if (ast.effects && Object.keys(ast.effects).length > 0)
|
|
38
|
+
disallowed.push('effects');
|
|
39
|
+
// Pattern events and structured patterns
|
|
40
|
+
if (ast.patternEvents && Object.keys(ast.patternEvents).length > 0) {
|
|
41
|
+
disallowed.push('patternEvents');
|
|
42
|
+
}
|
|
43
|
+
if (ast.sequenceItems && Object.keys(ast.sequenceItems).length > 0) {
|
|
44
|
+
disallowed.push('sequenceItems');
|
|
45
|
+
}
|
|
46
|
+
// Check for any other non-standard properties that might be added
|
|
47
|
+
const allowedKeys = new Set([
|
|
48
|
+
'insts', 'imports', 'pats', 'seqs', 'channels', 'arranges', 'play',
|
|
49
|
+
'chip', 'bpm', 'volume', 'metadata', 'effects', 'patternEvents', 'sequenceItems'
|
|
50
|
+
]);
|
|
51
|
+
for (const key of Object.keys(ast)) {
|
|
52
|
+
if (!allowedKeys.has(key) && key !== 'insts' && key !== 'imports') {
|
|
53
|
+
disallowed.push(`unknown property '${key}'`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (disallowed.length > 0) {
|
|
57
|
+
throw new Error(`Invalid .ins file "${source}": .ins files may only contain "inst" and "import" declarations. ` +
|
|
58
|
+
`Found: ${disallowed.join(', ')}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Load and parse a remote import file.
|
|
63
|
+
*/
|
|
64
|
+
async function loadRemoteImportFile(url, ctx) {
|
|
65
|
+
// Check for import cycles
|
|
66
|
+
if (ctx.importStack.includes(url)) {
|
|
67
|
+
const cycle = [...ctx.importStack, url].join(' -> ');
|
|
68
|
+
throw new Error(`Import cycle detected: ${cycle}`);
|
|
69
|
+
}
|
|
70
|
+
// Get or create remote cache
|
|
71
|
+
if (!ctx.remoteCache) {
|
|
72
|
+
ctx.remoteCache = new RemoteInstrumentCache(ctx.options.remoteOptions);
|
|
73
|
+
}
|
|
74
|
+
// Add to import stack
|
|
75
|
+
ctx.importStack.push(url);
|
|
76
|
+
try {
|
|
77
|
+
// Fetch from remote cache (handles caching internally)
|
|
78
|
+
const instruments = await ctx.remoteCache.fetch(url);
|
|
79
|
+
return instruments;
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
// Remove from import stack
|
|
83
|
+
ctx.importStack.pop();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Load and parse an import file (remote only in browser).
|
|
88
|
+
*/
|
|
89
|
+
async function loadImportFile(importSource, ctx) {
|
|
90
|
+
// Block local imports in browser
|
|
91
|
+
if (isLocalImport(importSource)) {
|
|
92
|
+
throw new Error(`Local imports are not supported in the browser for security reasons. ` +
|
|
93
|
+
`Import "${importSource}" cannot be loaded. ` +
|
|
94
|
+
`Use remote imports (https:// or github:) instead.`);
|
|
95
|
+
}
|
|
96
|
+
// Only remote imports are supported in browser
|
|
97
|
+
if (!isRemoteImport(importSource)) {
|
|
98
|
+
throw new Error(`Invalid import "${importSource}": Browser environment only supports remote imports. ` +
|
|
99
|
+
`Use "https://", "http://", or "github:" prefix for remote imports. ` +
|
|
100
|
+
`Local file imports require CLI environment.`);
|
|
101
|
+
}
|
|
102
|
+
return await loadRemoteImportFile(importSource, ctx);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Merge instrument maps with last-win semantics.
|
|
106
|
+
*/
|
|
107
|
+
function mergeInstruments(base, override, sourcePath, ctx) {
|
|
108
|
+
const result = { ...base };
|
|
109
|
+
for (const [name, inst] of Object.entries(override)) {
|
|
110
|
+
if (result[name] !== undefined) {
|
|
111
|
+
const message = `Instrument "${name}" from "${sourcePath}" overrides previously defined instrument`;
|
|
112
|
+
if (ctx.options.strictMode) {
|
|
113
|
+
throw new Error(message);
|
|
114
|
+
}
|
|
115
|
+
else if (ctx.options.onWarn) {
|
|
116
|
+
ctx.options.onWarn(message);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
result[name] = inst;
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Process all imports in an AST and return merged instruments.
|
|
125
|
+
*/
|
|
126
|
+
async function processImports(ast, ctx) {
|
|
127
|
+
let mergedInsts = {};
|
|
128
|
+
if (!ast.imports || ast.imports.length === 0) {
|
|
129
|
+
return mergedInsts;
|
|
130
|
+
}
|
|
131
|
+
for (const imp of ast.imports) {
|
|
132
|
+
const importedInsts = await loadImportFile(imp.source, ctx);
|
|
133
|
+
// Merge imported instruments (later imports override earlier ones)
|
|
134
|
+
mergedInsts = mergeInstruments(mergedInsts, importedInsts, imp.source, ctx);
|
|
135
|
+
}
|
|
136
|
+
return mergedInsts;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Resolve all imports in an AST and merge them into the instrument table.
|
|
140
|
+
* Returns a new AST with merged instruments.
|
|
141
|
+
* Browser version: Only supports remote imports (HTTP(S), GitHub).
|
|
142
|
+
*/
|
|
143
|
+
export async function resolveImports(ast, options = {}) {
|
|
144
|
+
const ctx = {
|
|
145
|
+
importStack: [],
|
|
146
|
+
options,
|
|
147
|
+
remoteCache: options.remoteCache,
|
|
148
|
+
};
|
|
149
|
+
// Process imports
|
|
150
|
+
const importedInsts = await processImports(ast, ctx);
|
|
151
|
+
// Merge imported instruments with local instruments (local overrides imported)
|
|
152
|
+
const finalInsts = mergeInstruments(importedInsts, ast.insts || {}, '<main>', ctx);
|
|
153
|
+
// Return new AST with merged instruments and cleared imports
|
|
154
|
+
return {
|
|
155
|
+
...ast,
|
|
156
|
+
insts: finalInsts,
|
|
157
|
+
imports: [], // Clear imports to prevent double-resolution
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Synchronous wrapper - not supported in browser (all remote imports are async).
|
|
162
|
+
* @deprecated Not available in browser context
|
|
163
|
+
*/
|
|
164
|
+
export function resolveImportsSync(_ast, _options = {}) {
|
|
165
|
+
throw new Error('resolveImportsSync is not available in browser context. ' +
|
|
166
|
+
'Use resolveImports() (async) instead for remote imports.');
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=importResolver.browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importResolver.browser.js","sourceRoot":"","sources":["../../src/song/importResolver.browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Import resolution for .ins files.
|
|
3
|
+
* Handles loading, caching, cycle detection, and merging of instrument definitions.
|
|
4
|
+
* Supports both local file imports and remote HTTP(S) imports.
|
|
5
|
+
*/
|
|
6
|
+
import { AST } from '../parser/ast.js';
|
|
7
|
+
import { RemoteInstrumentCache, RemoteImportOptions } from '../import/remoteCache.js';
|
|
8
|
+
export interface ImportResolverOptions {
|
|
9
|
+
/** Base file path for resolving relative imports */
|
|
10
|
+
baseFilePath?: string;
|
|
11
|
+
/** Additional search paths for resolving imports */
|
|
12
|
+
searchPaths?: string[];
|
|
13
|
+
/** Strict mode: treat instrument name overrides as errors instead of warnings */
|
|
14
|
+
strictMode?: boolean;
|
|
15
|
+
/** Warning handler */
|
|
16
|
+
onWarn?: (message: string, loc?: any) => void;
|
|
17
|
+
/** File system reader for testing */
|
|
18
|
+
readFile?: (filePath: string) => string;
|
|
19
|
+
/** File existence checker for testing */
|
|
20
|
+
fileExists?: (filePath: string) => boolean;
|
|
21
|
+
/** Allow absolute paths in imports (disabled by default for security) */
|
|
22
|
+
allowAbsolutePaths?: boolean;
|
|
23
|
+
/** Remote import options (timeout, HTTPS-only, etc.) */
|
|
24
|
+
remoteOptions?: RemoteImportOptions;
|
|
25
|
+
/** Remote instrument cache (reused across multiple resolve calls) */
|
|
26
|
+
remoteCache?: RemoteInstrumentCache;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve all imports in an AST and merge them into the instrument table.
|
|
30
|
+
* Returns a new AST with merged instruments.
|
|
31
|
+
* Supports both local file imports and remote HTTP(S) imports.
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveImports(ast: AST, options?: ImportResolverOptions): Promise<AST>;
|
|
34
|
+
/**
|
|
35
|
+
* Synchronous wrapper for resolveImports for backward compatibility.
|
|
36
|
+
* Does not support remote imports - throws an error if remote imports are encountered.
|
|
37
|
+
* @deprecated Use resolveImports (async) instead
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveImportsSync(ast: AST, options?: ImportResolverOptions): AST;
|
|
40
|
+
//# sourceMappingURL=importResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importResolver.d.ts","sourceRoot":"","sources":["../../src/song/importResolver.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,GAAG,EAAW,MAAM,kBAAkB,CAAC;AAKhD,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEtF,MAAM,WAAW,qBAAqB;IACpC,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,iFAAiF;IACjF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sBAAsB;IACtB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAC9C,qCAAqC;IACrC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,yCAAyC;IACzC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C,yEAAyE;IACzE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,wDAAwD;IACxD,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,qEAAqE;IACrE,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACrC;AA6ZD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,GAAG,CAAC,CA0Bd;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,qBAA0B,GAClC,GAAG,CA8BL"}
|