rimmel
Version:
A Streams-Oriented UI library for the Rx.Observable Universe
83 lines (80 loc) • 3.35 kB
JavaScript
import { SymbolObservature } from '../constants.js';
// @ts-nocheck
const CreateObservature = (initial) => {
let sources = [];
let subscribers = [];
const operators = [];
const output = new Observable((observer) => {
subscribers.push(observer);
return {
unsubscribe: () => {
subscribers = subscribers.filter(sub => sub !== observer);
}
};
});
const applyPipeline = (source) => {
const pipeline = operators.reduce((obs, [prop, args]) => obs[prop](...args), source);
return pipeline.subscribe({
next: (val) => subscribers.forEach(sub => sub.next?.(val) ?? sub(val)),
error: (error) => subscribers.forEach(sub => sub.error?.(error) ?? sub(error)),
complete: () => subscribers.forEach(sub => sub.complete?.())
});
};
return new Proxy(output, {
get(target, prop) {
switch (prop) {
case 'value':
return initial;
case Symbol.for('observable'):
case '@@observable':
return function () { return this; };
case '@@Observature':
case 'Observature':
case SymbolObservature:
return true;
case 'addSource':
return (_source) => {
sources.push(_source);
return target;
};
case 'type':
return undefined;
case 'next':
return (value) => applyPipeline(Observable.from([value]));
case 'error':
return (error) => subscribers.forEach(sub => sub.error?.(error) ?? sub(error));
case 'complete':
return () => subscribers.forEach(sub => sub.complete?.());
case 'subscribe':
return (_observer) => {
subscribers.push(_observer);
const starter = Observable.merge(...[].concat(sources, initial ? Observable.from([].concat(initial ?? [])) : []));
const subscription = applyPipeline(starter);
if (initial !== undefined) {
subscribers.forEach(sub => sub.next?.(initial));
}
return subscription;
};
default:
if (Observable.prototype.hasOwnProperty(prop)) {
return function (...args) {
// FIXME: this should return a new Observature
// (or a separate pipeline rather than modifying the original?)
// we still want to keep the same sources
operators.push([prop, args]);
return this;
};
}
return target[prop];
}
}
});
};
class Observature {
constructor(initial) {
return CreateObservature(initial);
}
}
const isObservature = (x) => x?.Observature || x[SymbolObservature];
export { CreateObservature, Observature, isObservature };
//# sourceMappingURL=observature.js.map