Quick reference: writing rag-eval-js scripts

Copy-paste reference for writing jsverbs: patterns, APIs, build commands, and troubleshooting.

Sections

Terminology & Glossary
📖 Documentation
Navigation
8 sectionsv0.1
📄 Quick reference: writing rag-eval-js scripts — glaze help how-to-write-rag-eval-js-scripts-quick-reference
how-to-write-rag-eval-js-scripts-quick-reference

Quick reference: writing rag-eval-js scripts

Copy-paste reference for writing jsverbs: patterns, APIs, build commands, and troubleshooting.

Topicrag-evalxgojascriptingjavascriptjsverbssqlitequick-referencerag-eval-jsdatabaseoutput

This is the quick-reference companion to the full tutorial. Read the full version for the conceptual foundation. Use this page when you are actively writing a verb and need the exact pattern.

Minimal verb template

__package__({ name: "myPackage", short: "What this package does" });

const db = require("db");

const DEFAULT_DB = "data/rag-eval.db";

function openDatabase(database) {
  const path = database || DEFAULT_DB;
  db.configure("sqlite3", path);
  return path;
}

function myVerb(database, limit) {
  openDatabase(database);
  const n = limit || 20;
  return db.query("SELECT * FROM sources LIMIT ?", n);
}

__verb__("myVerb", {
  short: "List sources",
  fields: {
    database: { type: "string", default: "data/rag-eval.db", help: "SQLite path" },
    limit: { type: "int", default: 20, help: "Max rows" }
  }
});

Module availability

require(...)Key functions
"db"configure(driver, dsn), query(sql, ...args), exec(sql, ...args), close()
"fs"readFileSync(p, enc), writeFileSync(p, data, enc), mkdirSync(p, opts), readdirSync(p), statSync(p), existsSync(p)
"express"app().get(pattern, fn), .post(...), .put(...), .delete(...), .all(...), .static(prefix, dir)
"markdown"parse(text), renderHTML(text), walk(ast, visitor), textContent(node), validate(value)
"sanitize"yaml.sanitize(text), yaml.lint(text), json.sanitize(text), json.strictParse(text)
"extract"all(text), markdownCodeBlocks(text), xmlTagged(text), frontmatter(text), validate(candidate)
"yaml"parse(text), stringify(obj), validate(text)
"path"join(...), resolve(...), basename(p), dirname(p), extname(p)

Dynamic SQL with optional filters

function documents(database, sourceId, status, limit) {
  openDatabase(database);
  let sql = `SELECT * FROM documents`;
  const conditions = [];
  const args = [];

  if (sourceId) { conditions.push("source_id = ?"); args.push(sourceId); }
  if (status) { conditions.push("status = ?"); args.push(status); }
  if (conditions.length) sql += " WHERE " + conditions.join(" AND ");
  sql += " LIMIT ?";
  args.push(limit || 20);

  return db.query(sql, args);
}

Export pattern with fs

const fs = require("fs");

function exportRows(rows, outDir) {
  fs.mkdirSync(outDir, { recursive: true });
  for (const row of rows) {
    fs.writeFileSync(
      `${outDir}/${row.id}.json`,
      JSON.stringify(row, null, 2),
      "utf-8"
    );
  }
  return { exported: rows.length, dir: outDir };
}

Markdown analysis pattern

const markdown = require("markdown");

function countHeadings(text) {
  const ast = markdown.parse(text);
  let n = 0;
  markdown.walk(ast, (node) => {
    if (node.Type === "heading") n++;
  });
  return n;
}

Express server pattern

const express = require("express");

function serveApi(database, port) {
  openDatabase(database);
  const app = express.app();

  app.get("/api/rows", (_req, res) => {
    res.json({ rows: db.query("SELECT * FROM sources") });
  });

  return { ok: true, port: port || 8787 };
}

Run long-lived:

rag-eval-js run script.js --keep-alive --http-listen 127.0.0.1:8788

Defensive sanitize access

const sanitize = require("sanitize");

const result = sanitize.yaml.sanitize(text);
const fixes = (result.Fixes || []).map((f) => f.Rule);
const issues = ((result.Issues || result.LintIssues) || []).map((i) => i.Message);

Rebuild after changes

cd cmd/rag-eval
xgoja build -f xgoja.yaml --output dist/rag-eval-js --xgoja-replace ../../../go-go-goja

Run and test

# List verbs
./dist/rag-eval-js myPackage --help

# Run verb
./dist/rag-eval-js myPackage my-verb --database ../../data/rag-eval.db

# JSON output
./dist/rag-eval-js myPackage my-verb --output json

# One-liner eval
./dist/rag-eval-js eval 'const db=require("db"); db.configure("sqlite3","data/rag-eval.db"); console.log(db.query("SELECT COUNT(*) AS n FROM documents")[0].n);'

Troubleshooting

ProblemSolution
database not configuredCall db.configure("sqlite3", path) before first query
.Fixes.map crashesUse (result.Fixes | | []).map(...)
Port 8787 busyPass --http-listen 127.0.0.1:8788 or use run --keep-alive
rows[0] is undefinedCheck rows.length before indexing
xgoja build module errorsVerify --xgoja-replace points to the right checkout
Verb not in helpRebuild with xgoja build after adding .js files

See Also

  • rag-eval-js help how-to-write-rag-eval-js-scripts — Full conceptual tutorial
  • rag-eval-js help explorer — Built-in explorer verbs
  • cmd/rag-eval/xgoja.yaml — Module declarations and build spec
  • cmd/rag-eval/jsverbs/ — Existing verb packages