@milichev/funexp
A simple template function expression generator.
Installation
NPM:
npm install @milichev/funexp
Yarn:
yarn add @milichev/funexp
Usage
With this tiny tagged expression processor, you can create a highly performant functions in runtime.
Example: making a data model processor
Here, we create a function that accepts a model object and patches its
properties:
- changes the
createdOn
type to Date
; - calculates the
total
value.
const toDate = jest.fn((value: Date | string | number) => new Date(value));
const discount = 0.75;
const calcTotal = jest.fn(
(price: number, discount: number) => price * discount
);
const myExpr = makeFun({ ctxVar: "methods", entryPrefix: "$m_" });
const exp = myExpr`
model.createdOn = ${toDate}(model.createdOn);
model.total = ${calcTotal}(model.price, ${discount});
return model;`;
const patcher = new Function("methods", "model", exp.src).bind(null, exp.ctx);
const createdOn = "2023-05-26T14:04:08.023Z";
const model = { createdOn, price: 100 };
const result = patcher(model);
expect(toDate).toHaveBeenCalledWith(createdOn);
expect(calcTotal).toHaveBeenCalledWith(100, 0.75);
expect(result).toBe(model);
expect(result.createdOn).toEqual(new Date(createdOn));
expect(result.total).toEqual(75);
Example: processing an array of arguments with the same template
Using the method each(values: any[])
, you can apply the same template to each value.
To inject the next value to the template, use the placeholder "%s"
as follows:
const model = {
a: 1,
b: 2,
c: 3,
};
const props: ReadonlyArray<keyof typeof model> = ["a", "b", "c"];
const actual = fun.each(props)`log(model.${"%s"});`;
expect(actual).toEqual<FunExpResult>({
src: "log(model.a);log(model.b);log(model.c);",
ctx: {},
});