// Convention: createFooBar is exported from ./create_foo_bar.js (one level up from
// this directory). Only "create*" names are allowed through, since the function name
// is used to build a dynamic import path.
const NAME_PATTERN = /^create[A-Z]\w*$/;
function toFileName(functionName) {
return functionName.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase();
}
/**
* Dynamically imports the module for a create* function and invokes it with args.
* Runs identically on the main thread or inside a worker.
*
* @param {String} functionName e.g. "createLocation"
* @param {Object} [args] the single named-parameters object the function expects
* @returns {*} whatever the create* function returns
*/
export async function callCreate(functionName, args) {
if (!NAME_PATTERN.test(functionName)) {
console.error(`${functionName} is not a create* function`);
return null;
}
const fileName = toFileName(functionName);
const module = await import(`../${fileName}.js`);
const fn = module[functionName];
if (typeof fn !== "function") {
console.error(`${fn} is not a function`);
return null;
}
const result = fn(args);
return result;
}
/**
* Expands a shimmed location (see createLocation's `shim` option) in place. Must run in the
* same worker that originally created the location in order to find a LocationTemplate by
* the location’s GUID (this may change).
*
* @param {Object} location a Location, possibly with descendants, produced by createLocation
* @returns {Object} the same location, fully expanded
*/
export async function callExpand(location) {
const { expandShim } = await import("../create_location.js");
return expandShim(location);
}