BrainUs LogoBrainUs AI
Code Examples

JavaScript/TypeScript Examples

Production-ready examples for Node.js, React, Next.js, Express

Complete JavaScript and TypeScript examples for integrating BrainUs API with popular frameworks.

Next.js App Router

// app/api/query/route.ts
import { BrainusAI } from "@brainus/ai";
import { NextRequest, NextResponse } from "next/server";

const client = new BrainusAI({
  apiKey: process.env.BRAINUS_API_KEY!,
});

export async function POST(request: NextRequest) {
  try {
    const { query, store_id = "default", filters } = await request.json();

    if (!query) {
      return NextResponse.json({ error: "Query is required" }, { status: 400 });
    }

    const result = await client.query({
      query,
      storeId: store_id,
      filters,
    });

    return NextResponse.json({
      answer: result.answer,
      citations: result.citations,
      metadata: result.metadata,
    });
  } catch (error: any) {
    return NextResponse.json(
      { error: error.message || "Internal server error" },
      { status: 500 }
    );
  }
}
// app/components/QueryChat.tsx
"use client";

import { useState } from "react";

export function QueryChat() {
  const [query, setQuery] = useState("");
  const [answer, setAnswer] = useState("");
  const [loading, setLoading] = useState(false);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setLoading(true);

    try {
      const response = await fetch("/api/query", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ query }),
      });

      const data = await response.json();

      if (data.error) {
        alert(data.error);
      } else {
        setAnswer(data.answer);
      }
    } catch (error) {
      console.error(error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="max-w-2xl mx-auto p-6">
      <form onSubmit={handleSubmit} className="space-y-4">
        <input
          type="text"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          placeholder="Ask a question..."
          className="w-full p-3 border rounded"
          disabled={loading}
        />
        <button
          type="submit"
          disabled={loading}
          className="w-full bg-blue-500 text-white p-3 rounded disabled:opacity-50"
        >
          {loading ? "Loading..." : "Ask"}
        </button>
      </form>

      {answer && (
        <div className="mt-6 p-4 bg-gray-50 rounded">
          <h3 className="font-semibold mb-2">Answer:</h3>
          <p>{answer}</p>
        </div>
      )}
    </div>
  );
}

React Hook

// hooks/useBrainUs.ts
import { useState, useCallback } from "react";

interface QueryResult {
  answer: string;
  citations: any[];
  metadata: any;
}

export function useBrainUs() {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [data, setData] = useState<QueryResult | null>(null);

  const query = useCallback(async (question: string, storeId = "default") => {
    setLoading(true);
    setError(null);

    try {
      const response = await fetch("/api/query", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ query: question, store_id: storeId }),
      });

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }

      const result = await response.json();
      setData(result);
      return result;
    } catch (err: any) {
      setError(err.message);
      throw err;
    } finally {
      setLoading(false);
    }
  }, []);

  return { query, loading, error, data };
}

// Usage in component
function MyComponent() {
  const { query, loading, error, data } = useBrainUs();

  const handleAsk = async () => {
    await query("What is photosynthesis?");
  };

  return (
    <div>
      <button onClick={handleAsk} disabled={loading}>
        Ask Question
      </button>
      {loading && <p>Loading...</p>}
      {error && <p>Error: {error}</p>}
      {data && <p>Answer: {data.answer}</p>}
    </div>
  );
}

Express.js with Caching

// server.js
require("dotenv").config();
const express = require("express");
const { BrainusAI, RateLimitError } = require("@brainus/ai");
const NodeCache = require("node-cache");

const app = express();
app.use(express.json());

// Cache responses for 1 hour
const cache = new NodeCache({ stdTTL: 3600 });

const client = new BrainusAI({
  apiKey: process.env.BRAINUS_API_KEY,
});

app.post("/api/query", async (req, res) => {
  const { query, store_id = "default" } = req.body;

  if (!query) {
    return res.status(400).json({ error: "Query is required" });
  }

  // Check cache
  const cacheKey = `${query}-${store_id}`;
  const cached = cache.get(cacheKey);
  if (cached) {
    return res.json({ ...cached, cached: true });
  }

  try {
    const result = await client.query({
      query,
      storeId: store_id,
    });

    const response = {
      answer: result.answer,
      citations: result.citations,
      metadata: result.metadata,
    };

    // Cache the response
    cache.set(cacheKey, response);

    res.json({ ...response, cached: false });
  } catch (error) {
    if (error instanceof RateLimitError) {
      return res.status(429).json({
        error: "Rate limit exceeded",
        retry_after: error.retryAfter,
      });
    }

    res.status(500).json({ error: error.message });
  }
});

app.listen(3000, () => {
  console.log("Server running on port 3000");
});

TypeScript with Error Handling

import { BrainusAI, BrainusError, RateLimitError } from "@brainus/ai";

const client = new BrainusAI({
  apiKey: process.env.BRAINUS_API_KEY!,
});

async function robustQuery(
  query: string,
  maxRetries: number = 3
): Promise<string | null> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const result = await client.query({
        query,
        storeId: "default",
      });

      return result.answer;
    } catch (error) {
      if (error instanceof RateLimitError) {
        console.log(`Rate limited. Waiting ${error.retryAfter}s...`);
        await new Promise((resolve) =>
          setTimeout(resolve, error.retryAfter * 1000)
        );
        continue;
      }

      if (error instanceof BrainusError) {
        console.error(`API Error: ${error.message}`);
        return null;
      }

      // Unknown error
      console.error(`Unexpected error:`, error);
      return null;
    }
  }

  console.error(`Failed after ${maxRetries} attempts`);
  return null;
}

// Usage
const answer = await robustQuery("What is photosynthesis?");
console.log(answer);

Streaming Responses (Coming Soon)

// Future API
import { BrainusAI } from "@brainus/ai";

const client = new BrainusAI({
  apiKey: process.env.BRAINUS_API_KEY!,
});

async function* streamQuery(query: string) {
  const stream = await client.queryStream({
    query,
    storeId: "default",
  });

  for await (const chunk of stream) {
    yield chunk.text;
  }
}

// Usage
for await (const text of streamQuery("Explain photosynthesis")) {
  process.stdout.write(text);
}

Batch Processing

const { BrainusAI } = require("@brainus/ai");

const client = new BrainusAI({
  apiKey: process.env.BRAINUS_API_KEY,
});

async function processBatch(queries, batchSize = 5) {
  const results = [];

  for (let i = 0; i < queries.length; i += batchSize) {
    const batch = queries.slice(i, i + batchSize);

    const batchResults = await Promise.all(
      batch.map(async (query) => {
        try {
          const result = await client.query({ query, storeId: "default" });
          return { query, answer: result.answer, error: null };
        } catch (error) {
          return { query, answer: null, error: error.message };
        }
      })
    );

    results.push(...batchResults);

    // Rate limiting: wait between batches
    if (i + batchSize < queries.length) {
      await new Promise((resolve) => setTimeout(resolve, 1000));
    }
  }

  return results;
}

// Usage
const queries = [
  "What is photosynthesis?",
  "Explain the water cycle",
  "What causes earthquakes?",
  "Who was Albert Einstein?",
];

// Note: Ensure you are in an async context
// const results = await processBatch(queries);
// console.log(results);

All examples are available in our GitHub repository.

Next Steps

On this page