reactive-observables
Version:
Framework-agnostic observables and computed properties similar to Knockout and Vue, built on RxJS
36 lines (28 loc) • 1.41 kB
text/typescript
import { TrackedComputedSubject } from "../tracked-computed-subject";
interface ComputedProperty<T> {
subject: TrackedComputedSubject<T>;
}
type ComputedPropertyList<T> = {
[K in keyof T]: ComputedProperty<T[K]>;
};
const ComputedPropertyListKey = "_computedProperties";
export const getComputedPropertyList = <T>(obj: T) => ((obj as any)[ComputedPropertyListKey] = (obj as any)[ComputedPropertyListKey] || {}) as ComputedPropertyList<T>;
export const getOrSetupComputedProperty = <T, K extends keyof T>(obj: T, name: K, getter: () => T[K]): TrackedComputedSubject<T[K]> => {
const list = getComputedPropertyList(obj);
const existing = list[name];
if (!existing) {
const subject = new TrackedComputedSubject<T[K]>(getter.bind(obj));
list[name] = { subject };
}
return list[name].subject;
};
export const getComputedProperty = <T, K extends keyof T>(obj: T, name: K): TrackedComputedSubject<T[K]> => {
const list = getComputedPropertyList(obj);
if (!list[name]) {
obj[name]; // Has not been initialized, so initialized it now
// Lazy initialization seems to be the correct step here? See the long comment in tracked-property.ts
//console.info("computed initialized lazily via getComputedProperty", obj, name, list);
//throw new Error("Property accessed before initialized: " + name);
}
return list[name].subject;
};