function loadToJs()

in packages/sqrl/src/js/SqrlJs.ts [149:196]


function loadToJs(expr: Expr, state: JsState) {
  const loadAsSlots = expr.load.map((slot) => ({
    slot,
    type: "value",
  }));
  const slots = expr.load.map((slot) => slot.getIndex());
  const loadJson = JSON.stringify(slots);

  if (expr.exprs.length === 1) {
    const subexpr = expr.exprs[0];

    // Optimise loading of a single slot to just fetching that slot
    if (expr.load.length === 1 && deepEqual(subexpr, loadAsSlots[0])) {
      return new PromiseJsExpr(`this.fetch(${slots[0]})`);
    }

    // Simple list from different slots
    if (deepEqual(subexpr, { type: "list", exprs: loadAsSlots })) {
      return new PromiseJsExpr(`this.load(${loadJson})`);
    }

    // Simple function call from slots
    if (subexpr.type === "call") {
      if (
        deepEqual(subexpr, {
          exprs: loadAsSlots,
          func: subexpr.func,
        })
      ) {
        if (expr.load.length === 1) {
          return new PromiseJsExpr(
            `this.fetch(${slots[0]}).then(functions.${subexpr.func})`
          );
        }
        return new PromiseJsExpr(
          `this.load(${loadJson}).spread(functions.${subexpr.func})`
        );
      }
    }
  }

  // @TODO: At some point we should handle more than one expression here
  invariant(expr.exprs.length === 1, "Expected single expression");

  const [subexpr] = expr.exprs.map((e) => exprToJs(e, state));
  const fnCallJs = state.pushExprJs(subexpr).toCallableString();
  return new PromiseJsExpr(`this.load(${loadJson}).then(${fnCallJs})`);
}