mahler
Version:
A automated task composer and HTN based planner for building autonomous system agents
80 lines • 2.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Target = exports.UNDEFINED = void 0;
exports.UNDEFINED = Symbol('m_undefined');
function globToRegExp(glob) {
const parts = glob.split('*');
const regex = parts.map((p) => p.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
return new RegExp(`^${regex.join('[^/]*')}$`);
}
/**
* Create a new relative target from the given strict target and the
* current state.
*
* This will look any missing properties on the target and replace them with
* `UNDEFINED` symbols in order to mark them for deletion.
*
* Because sometimes it is useful to have properties on the current state
* that are not needed on the target, this function receives a
* list of 'globs' indicating which properties to ignore. Properties in the `ignoreGlobs`
* list will be skipped when marking properties to be deleted.
*
* Example.
* ```
* // Current state
* const s = {x: 1, y:0, lastUpdated: '20240408T12:00:00Z'};
*
* // Calculate target state
* const target = Target.fromStrict(s, {y: 1}, ['lastUpdated']);
* console.log(target); // {x: UNDEFINED, y: 1}
* ```
*
* Note that glob support is very limited, and only supports `*` as special characters.
*/
function fromStrict(state, target, ignoreGlobs = []) {
const queue = [
{ s: state, t: target, p: '' },
];
const ignore = ignoreGlobs.map(globToRegExp);
while (queue.length > 0) {
const { s, t, p } = queue.shift();
// Don't recurse into arrays
if (Array.isArray(s) || Array.isArray(t)) {
continue;
}
for (const key of Object.keys(s)) {
// If the target is explicitely set as `undefined` replace
// the target with the `UNDEFINED` symbol
if (key in t && t[key] === undefined && s[key] !== undefined) {
t[key] = exports.UNDEFINED;
}
// If the key doesn't exist on the target but the path
// matches one the globs, ignore it
else if (!(key in t) && ignore.some((r) => r.test(`${p}/${key}`))) {
continue;
}
// If the path does not match any glob, mark the element to be
// deleted
else if (!(key in t)) {
// UNDEFINED means delete the value
t[key] = exports.UNDEFINED;
}
// Otherwise, if the value is an object, we need to recurse
else if (typeof t[key] === 'object') {
queue.push({ s: s[key], t: t[key], p: `${p}/${key}` });
}
}
}
return target;
}
exports.Target = {
/**
* Create a new relative target from the given strict target and the
* current state.
*
* @deprecated to be replaced by fromStrict
*/
from: fromStrict,
fromStrict,
};
//# sourceMappingURL=target.js.map