@lifaon/rx-js-light
Version:
Blazing fast Observables
62 lines (61 loc) • 2.79 kB
JavaScript
import {createMulticastReplayLastSource} from "../observer-observable-pair/build-in/source/built-in/replay-last-source/derived/create-multicast-replay-last-source.mjs";
import {pipeObservable} from "../observable/helpers/piping/pipe-observable/pipe-observable.mjs";
import {mapObservablePipe} from "../observable/pipes/built-in/without-notifications/observer-pipe-related/map/map-observable-pipe.mjs";
import {getObjectPropertyPathValue, getOptionalObjectPropertyPathValue} from "../misc/helpers/property-path/get-object-property-path-value.mjs";
export function createObservableProxy(data, path = []) {
let cachedSubscribe;
const cachedSourcesForArray = [];
const cachedProxiesForArray = [];
let cachedSubscribeArray;
const cachedProxies = new Map();
return new Proxy(Object.create(null), {
get: (target, propertyKey) => {
if (propertyKey === '$') {
if (cachedSubscribe === void 0) {
cachedSubscribe = pipeObservable(data, [mapObservablePipe(data => {
return getOptionalObjectPropertyPathValue(data, path);
})]);
}
return cachedSubscribe;
} else if (propertyKey === '$array') {
if (cachedSubscribeArray === void 0) {
cachedSubscribeArray = pipeObservable(data, [mapObservablePipe(data => {
const items = getObjectPropertyPathValue(data, path);
if (Array.isArray(items)) {
const itemsLength = items.length;
const cachedProxiesForArrayLength = cachedProxiesForArray.length;
if (cachedProxiesForArrayLength < itemsLength) {
cachedSourcesForArray.length = itemsLength;
cachedProxiesForArray.length = itemsLength;
for (let i = cachedProxiesForArrayLength; i < itemsLength; i++) {
const source = createMulticastReplayLastSource({
initialValue: items[i]
});
cachedSourcesForArray[i] = source.emit;
cachedProxiesForArray[i] = createObservableProxy(source.subscribe);
}
}
for (let i = 0; i < itemsLength; i++) {
cachedSourcesForArray[i](items[i]);
}
return cachedProxiesForArray;
} else {
throw new Error(`Not an array`);
}
})]);
}
return cachedSubscribeArray;
} else {
let cachedProxy = cachedProxies.get(propertyKey);
if (cachedProxy === void 0) {
cachedProxy = createObservableProxy(data, path.concat(propertyKey));
cachedProxies.set(propertyKey, cachedProxy);
}
return cachedProxy;
}
},
set: () => {
throw new Error(`The proxy is readonly`);
}
});
}