djembe
Version:
A rhythm maker which emits any data with the given rhythm periodically
303 lines (246 loc) • 7.65 kB
JavaScript
function _defineProperty$1(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys$1(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2$1(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys$1(Object(source), true).forEach(function (key) {
_defineProperty$1(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys$1(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var DEFAULT_OPTIONS$1 = {
steps: 32,
steppers: 7,
initialState: null
};
function epicles() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var mergedOptions = _objectSpread2(_objectSpread2({}, DEFAULT_OPTIONS$1), options);
var steps = mergedOptions.steps,
steppers = mergedOptions.steppers,
initialState = mergedOptions.initialState;
if (steps < 2) {
throw new Error('step size must be at least 2');
}
if (initialState && initialState.length !== steps) {
throw new Error('initial state length must be equal to step size');
}
var state = initialState ? sanetizeState(initialState) : Array(steppers).fill(0);
var subscribers = [];
function sanetizeState(state) {
return state.map(function (stepper) {
return stepper > 0 ? stepper % steps : (steps - Math.abs(stepper) % steps) % steps;
});
}
function cyclicIncrement(value) {
return (value + 1) % steps;
}
function emitTickEvent(event) {
subscribers.forEach(function (subscriber) {
subscriber(event);
});
}
function increment(state, index) {
var tickEvents = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var nextState = _toConsumableArray(state);
nextState[index] = cyclicIncrement(nextState[index]);
tickEvents.push({
step: nextState[index],
stepper: index
});
if (nextState[index] === 0 && index < state.length - 1) {
return increment(nextState, index + 1, tickEvents);
}
return {
nextState: nextState,
tickEvents: tickEvents
};
}
function tick() {
var _increment = increment(state, 0, []),
nextState = _increment.nextState,
tickEvents = _increment.tickEvents;
state = nextState;
emitTickEvent(tickEvents);
}
function subscribe(callback) {
if (subscribers.find(callback)) return;
subscribers.push(callback);
var unsubscribe = function unsubscribe() {
subscribers = subscribers.filter(function (subscriber) {
return subscriber !== callback;
});
};
return unsubscribe;
}
function getState() {
return state.map(function (value, index) {
return {
stepper: index,
step: value
};
});
}
return {
tick: tick,
subscribe: subscribe,
getState: getState
};
}
var DEFAULT_OPTIONS = {
steps: 32,
steppers: 7,
ticks: []
};
function Djembe() {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var subscribers = [];
var options = _objectSpread2$1(_objectSpread2$1({}, DEFAULT_OPTIONS), opts);
var steps = options.steps,
steppers = options.steppers,
initialState = options.initialState;
var ticks = options.ticks;
var epicle = epicles({
steps: steps,
steppers: steppers,
initialState: initialState
});
epicle.subscribe(handleTickEvents);
function handleTickEvents(events) {
var emittedTicks = ticks.filter(function (tick) {
var shouldBeEmitted = !!events.find(function (event) {
return event.step === tick.step && event.stepper === tick.stepper;
});
return shouldBeEmitted;
});
var state = epicle.getState();
emit(emittedTicks, state);
}
function emit(ticks, state) {
subscribers.forEach(function (subscriber) {
subscriber({
ticks: ticks,
state: state
});
});
}
function tick() {
epicle.tick();
}
function subscribe(callback) {
if (subscribers.find(callback)) return;
subscribers.push(callback);
var unsubscribe = function unsubscribe() {
subscribers = subscribers.filter(function (subscriber) {
return subscriber !== callback;
});
};
return unsubscribe;
}
function setTicks(nextTicks) {
ticks = nextTicks;
}
return {
subscribe: subscribe,
tick: tick,
setTicks: setTicks
};
}
export { Djembe };