mahler
Version:
A automated task composer and HTN based planner for building autonomous system agents
150 lines • 5.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Lens = void 0;
const assert_1 = require("./assert");
const is_array_index_1 = require("./is-array-index");
const path_1 = require("./path");
const pointer_1 = require("./pointer");
function params(template, path) {
const templateParts = path_1.Path.split(template);
const parts = path_1.Path.split(path);
(0, assert_1.default)(parts.length === templateParts.length, `Path '${path} should match its template '${template}'`);
const args = {};
for (const templateElem of templateParts) {
const pathElem = parts.shift();
if (templateElem.startsWith(':')) {
const key = templateElem.slice(1);
// Convert the value to a number if it is an array index
args[key] = (0, is_array_index_1.isArrayIndex)(pathElem) ? +pathElem : pathElem;
}
else {
(0, assert_1.default)(templateElem === pathElem, `Path '${path} should match its template '${template}'`);
}
}
return args;
}
function context(lens, path, target) {
const lensPath = path_1.Path.from(lens);
// Get route parameters
const args = params(lensPath, path);
return {
...args,
target,
path,
};
}
function createLens(s, p) {
try {
return pointer_1.Pointer.from(s, p);
}
catch (e) {
// The lens is a bit more permissive than pointer as a task
// may be relevant to a path on the state that is yet to be created
if (e instanceof pointer_1.InvalidPointer) {
return undefined;
}
throw e;
}
}
/**
* Test if a lens given as first argument starts
* with the path given as second argument
*/
function startsWith(lens, path) {
const pathParts = path_1.Path.split(path);
const lensParts = path_1.Path.split(lens);
// There will never be a match in this case
// no point in searching
if (lensParts.length < pathParts.length) {
return false;
}
// Find the starting context comparing the
// initial path with the lens
for (const k of pathParts) {
// We know the key cannot be undefined because
// of the length comparison before
const key = lensParts.shift();
// If the keys don't match terminate the search
if (!key.startsWith(':') && k !== key) {
return false;
}
}
return true;
}
/**
* Find all elements of the given state object that match
* the lens, starting at `initialPath`
*
* This function never throws, if the lens does not
* start with the initial path or there are no matches
* the function will return an empty array
*/
function findAll(state, lens, initialPath = path_1.Path.from('/')) {
const initialParts = path_1.Path.split(initialPath);
const lensParts = path_1.Path.split(lens);
// There will never be a match in this case
// no point in searching
if (lensParts.length < initialParts.length) {
return [];
}
let initialTarget = state;
// Find the starting context comparing the
// initial path with the lens
for (const k of initialParts) {
// No point in continuing the search in this case
if (initialTarget == null || typeof initialTarget !== 'object') {
return [];
}
// We know the key cannot be undefined because
// of the length comparison before
const key = lensParts.shift();
// If the key starts with `:` we continue searching
if (!key.startsWith(':') && (k !== key || !(k in initialTarget))) {
// The initial path does not match the lens or
// the state
return [];
}
initialTarget = initialTarget[k];
}
let contextList = [
{ target: initialTarget, path: initialPath },
];
for (const key of lensParts) {
contextList = contextList.flatMap(({ target, path }) => {
// This is not a valid search path so we ignore it
if (target == null || typeof target !== 'object') {
return [];
}
if (key.startsWith(':')) {
// If the key is a varible, we need to add all sub elements
// of the current object
return Object.entries(target).map(([k, v]) => ({
target: v,
path: path_1.Path.join(path, k),
}));
}
else if (key in target) {
// Otherwise just return the subelement of
// the current object
return [
{
target: target[key],
path: path_1.Path.join(path, key),
},
];
}
else {
return [];
}
});
}
return contextList.map(({ path }) => path);
}
exports.Lens = {
context,
args: params,
from: createLens,
findAll,
startsWith,
};
//# sourceMappingURL=lens.js.map