Now, all browsers support async/await feature, so does Node.js. The Javascript arrays resulting from the XPath/XQuery parser can now be converted into Javascript functions.
To evaluate an expression, the context is passed as unique parameter
to the Javascript function. Its body contains a sequence of instructions
with a Reverse Polish Notation order: arguments and parameters are stacked
before function calls. Path evaluations require if
statements to stop
when a step returns an empty sequence. Predicates are performed with
inline functions to be called for each sequence item. Error management is
implemented throwing Javascript exceptions.
For example,
concat('Hello ', PersonGivenName, '. We hope you like XForms!')
Becomes
ctx => { ctx.xqx_stringConstantExpr('Hello '); ctx.xqx_pathExpr(); ctx.xqx_xpathAxis_child(); ctx.xqx_nameTest("PersonGivenName"); ctx.restoreContext(); ctx.xs_string_1(); ctx.xqx_stringConstantExpr('. We hope you like XForms!'); ctx.fn_concat(3); return ctx; };
This is optimized for Javascript interpreter own call stack and
async
/await
use is reduced to minimal.
For example,
doc('r2d2.urdf.xml')/robot/joint[@name eq 'swivel']
Becomes
async ctx => {
ctx.xqx_pathExpr();
await ctx.xqx_filterExpr_async(async ctx => {
ctx.xqx_stringConstantExpr('r2d2.urdf.xml');
await ctx.fn_doc_1_async();
return ctx;
});
if (ctx.item.isNotEmpty()) {
ctx.xqx_xpathAxis_child();
ctx.xqx_nameTest("robot");
if (ctx.item.isNotEmpty()) {
ctx.xqx_xpathAxis_child();
ctx.xqx_nameTest("joint");
if (ctx.item.isNotEmpty()) {
ctx.xqx_predicateExpr(ctx => {
ctx.xqx_pathExpr();
ctx.xqx_xpathAxis_attribute();
ctx.xqx_nameTest("name");
ctx.restoreContext();
ctx.atomize();
ctx.xqx_stringConstantExpr('swivel');
ctx.xqx_valueComp(Fleur.eqOp);
return ctx;
});
}
}
}
ctx.restoreContext();
return ctx;
};
It is also enabling static optimization when generating the Javascript source. For example, atomizing and node sorting are not always necessary when calling a function. Instead of Javascript, with XSLT, a more sophisticated transpiler could be written to transform XQueryX to Javascript functions.
The fleur()
Javascript function returns a type-explicit
serialization which simulates an equivalent XQuery expression for the
result of evaluation (more explicit than adaptative output).
For example,
fleur("xs:date('2021-05-21') - xs:date('2021-05-10')")
Returns
"xs:dayTimeDuration('P11D')"