diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 671566be..aaa6421b 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -7,26 +7,32 @@ This program is free software: you can redistribute it and/or modify it under th import { Pattern, register, sequence } from './pattern.mjs'; export function createParam(names) { - const name = Array.isArray(names) ? names[0] : names; + let isMulti = Array.isArray(names); + names = !isMulti ? [names] : names; + const name = names[0]; - var withVal; - if (Array.isArray(names)) { - withVal = (xs) => { - if (Array.isArray(xs)) { - const result = {}; - xs.forEach((x, i) => { - if (i < names.length) { - result[names[i]] = x; - } - }); - return result; - } else { - return { [name]: xs }; - } - }; - } else { - withVal = (x) => ({ [name]: x }); - } + const withVal = (xs) => { + let bag; + // check if we have an object with an unnamed control (.value) + if (typeof xs === 'object' && xs.value !== undefined) { + bag = xs; // grab props that are already there + xs = xs.value; // grab the unnamed control for this one + delete bag.value; + } + if (isMulti && Array.isArray(xs)) { + const result = bag || {}; + xs.forEach((x, i) => { + if (i < names.length) { + result[names[i]] = x; + } + }); + return result; + } else if (bag) { + return { ...bag, [name]: xs }; + } else { + return { [name]: xs }; + } + }; const func = (...pats) => sequence(...pats).withValue(withVal); diff --git a/packages/core/test/controls.test.mjs b/packages/core/test/controls.test.mjs index aa66bf98..69d63645 100644 --- a/packages/core/test/controls.test.mjs +++ b/packages/core/test/controls.test.mjs @@ -25,4 +25,8 @@ describe('controls', () => { { s: 'sd', n: 4, gain: 0.5 }, ]); }); + it('should support nested controls', () => { + expect(s(mini('bd').pan(1)).firstCycleValues).toEqual([{ s: 'bd', pan: 1 }]); + expect(s(mini('bd:1').pan(1)).firstCycleValues).toEqual([{ s: 'bd', n: 1, pan: 1 }]); + }); });