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