@pexip/signal
Version:
an observer pattern while avoiding boilerplate code. https://en.wikipedia.org/wiki/Signals_and_slots
44 lines (43 loc) • 1.5 kB
JavaScript
import { createSignal } from './signal';
export const combine = (...signals) => {
const latest = Array.from(signals, _ => undefined);
let detachCombinedSignals = [];
const attach = () => {
detachCombinedSignals = signals.map((signal, i) => signal.add(value => {
latest[i] = value;
combinedSignal.emit(latest);
}));
};
const detach = () => {
for (const detach of detachCombinedSignals) {
detach();
}
};
const combinedSignal = createSignal();
const combinedSignalProxy = new Proxy(combinedSignal, {
get: (target, p, args) => {
switch (p) {
case 'add':
return (...args) => {
const value = target[p](...args);
if (detachCombinedSignals.length === 0 &&
combinedSignal.size > 0) {
attach();
}
return value;
};
case 'remove':
return (...args) => {
const value = target[p](...args);
if (combinedSignal.size === 0) {
detach();
}
return value;
};
default:
return Reflect.get(target, p, args);
}
},
});
return combinedSignalProxy;
};