run = async (
  table_id,
  viewname,
  { list_view, show_view, list_width, subtables },
  state,
  extraArgs,
  { getRowQuery }
) => {
  const table = Table.findOne({ id: table_id });
  const fields = table.getFields();
  readState(state, fields);

  var lresp;
  if (list_view) {
    const lview = await View.findOne({ name: list_view });
    if (!lview)
      throw new InvalidConfiguration(
        `View ${viewname} incorrectly configured: cannot find view ${list_view}`
      );
    const state1 = lview.combine_state_and_default_state(state);
    lresp = await lview.run(state1, {
      ...extraArgs,
      onRowSelect: (v) => `select_id('${v.id}', this)`,
      removeIdFromstate: true,
    });
  }

  var sresp = "";
  if (show_view) {
    const sview = await View.findOne({ name: show_view });
    if (!sview)
      throw new InvalidConfiguration(
        `View ${viewname} incorrectly configured: cannot find view ${show_view}`
      );
    sresp = await sview.run(state, extraArgs);
  }
  var reltbls = {};
  var myrow;
  const { uniques } = splitUniques(fields, state, true);

  if (Object.keys(uniques).length > 0) {
    var id;
    if (state.id) id = state.id;
    else {
      myrow = getRowQuery(uniques);
      if (!myrow) return `Not found`;
      id = myrow.id;
    }
    for (const relspec of Object.keys(subtables || {})) {
      if (subtables[relspec]) {
        const [reltype, rel] = relspec.split(":");
        switch (reltype) {
          case "ChildList":
          case "OneToOneShow":
            const [vname, reltblnm, relfld] = rel.split(".");
            const tab_name = reltblnm;
            const subview = await View.findOne({ name: vname });
            if (!subview)
              throw new InvalidConfiguration(
                `View ${viewname} incorrectly configured: cannot find view ${vname}`
              );
            else {
              const allPagings = extractPagings(state);
              const subresp = await subview.run(
                { [relfld]: id, ...allPagings },
                extraArgs
              );
              reltbls[tab_name] = subresp;
            }
            break;
          case "ParentShow":
            const [pvname, preltblnm, prelfld] = rel.split(".");
            if (!myrow) myrow = await getRowQuery({ id });
            if (!myrow) continue;
            const ptab_name = prelfld;
            const psubview = await View.findOne({ name: pvname });
            if (!psubview)
              throw new InvalidConfiguration(
                `View ${viewname} incorrectly configured: cannot find view ${pvname}`
              );
            else {
              const psubresp = await psubview.run(
                { id: myrow[prelfld] },
                extraArgs
              );

              reltbls[ptab_name] = psubresp;
            }
            break;
          default:
            break;
        }
      }
    }
  }
  const relTblResp =
    Object.keys(reltbls).length === 1
      ? [h6(Object.keys(reltbls)[0]), reltbls[Object.keys(reltbls)[0]]]
      : tabs(reltbls);
  if (lresp) {
    if (list_width === 12) return lresp;
    return div(
      { class: "row" },
      div({ class: `col-sm-${list_width || 6}` }, lresp),
      div(
        { class: `col-sm-${12 - (list_width || 6)}` },
        div(
          {
            class: "d-inline",
            "data-sc-embed-viewname": show_view,
          },
          sresp
        ),
        relTblResp
      )
    );
  } else {
    return div(
      div(
        {
          class: "d-inline",
          "data-sc-embed-viewname": show_view,
        },
        sresp
      ),
      relTblResp
    );
  }
}
@param {string} table_id
@param {string} viewname
@param {object} opts
@param {string} opts.list_view
@param {string} opts.show_view
@param {object} opts.subtables
@param {*} state
@param {*} extraArgs
@returns {Promise<div>}