UNPKG

mahler

Version:

A automated task composer and HTN based planner for building autonomous system agents

98 lines 3.35 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.observe = observe; const path_1 = require("../path"); const patch_1 = require("./patch"); function isObject(value) { return value !== null && typeof value === 'object'; } function appendToPath(key, path) { return key === '_' && path.length === 0 ? path : path.concat(String(key)); } function buildProxy(r, u, next, path = []) { return new Proxy(u, { set(target, prop, value) { const childPath = appendToPath(prop, path); const existsBefore = prop in target; let valueProxy = value; if (isObject(value)) { // If we are re-assigning a key with a new object we need to // observe that object too. We pass an empty array to changes as we don't want // to reverse those changes valueProxy = observeObject(r, value, next, childPath); } const res = Reflect.set(target, prop, valueProxy); // Do not notify on array length changes if (res) { if (Array.isArray(target) && prop === 'length') { return res; } if (existsBefore) { // Notify the observer next({ op: 'update', path: path_1.Path.from(childPath), target: value, }); } else { next({ op: 'create', path: path_1.Path.from(childPath), target: value, }); } } return res; }, deleteProperty(target, prop) { const res = Reflect.deleteProperty(target, prop); if (res) { const childPath = appendToPath(prop, path); next({ op: 'delete', path: path_1.Path.from(childPath) }); } return res; }, }); } function observeArray(r, u, next, path = []) { u = u.map((v, i) => { if (isObject(v)) { const newPath = path.concat(String(i)); return observeObject(r, v, next, newPath); } return v; }); return buildProxy(r, u, next, path); } function observeObject(r, u, next, path = []) { if (Array.isArray(u)) { return observeArray(r, u, next, path); } // Recursively observe existing properties of the object u = Object.fromEntries(Object.getOwnPropertyNames(u).map((key) => { const v = u[key]; if (isObject(v)) { return [key, observeObject(r, v, next, appendToPath(key, path))]; } return [key, v]; })); return buildProxy(r, u, next, path); } /** * Communicates the changes performed by a function on an object * reference to an observer. * * @param fn The function to execute * @param observer The observer to notify of changes * @returns an intrumented function */ function observe(fn, observer) { return function (ref) { return fn(observeObject(ref, ref, (change) => { (0, patch_1.applyPatch)(ref, change); observer.next(change); })); }; } //# sourceMappingURL=observe.js.map