SingleStore Elegance SDK
The Elegance SDK is an SDK for quickly building real-time AI full-stack JavaScript applications using SingleStoreDB with support for MySQL and Kai (support for Mongo APIs) connection types and the OpenAI API. It provides a set of ready-made tools for implementing various types of functionality when you need to transact, analyze, and contextualize data in real-time or build real-time AI apps.
Features
- Vector search
- Chat completions
- File embeddings generation (csv, pdf)
- SQL and aggregate queries
- SQL and Kai (MongoDB) database connections support
- Ready-to-use Node.js controllers and React.js hooks
Installation
npm install @singlestore/elegance-sdk
Usage
This guide will show you how to use the SDK in Express.js and React.js.
- Create a
eleganceServerClient.ts
file - Import the
createEleganceServerClient
function from @singlestore/elegance-sdk/server
import { createEleganceServerClient } from "@singlestore/elegance-sdk/server";
export const eleganceServerClient = createEleganceServerClient("mysql", {
connection: {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
},
openai: {
apiKey: process.env.OPENAI_API_KEY
}
});
- Create a route handler for
elegance/:route
(using Express.js as an example).
import express from "express";
import type { Routes } from "@singlestore/elegance-sdk/server";
import { eleganceServerClient } from "@/services/eleganceServerClient";
export const eleganceRouter = express.Router();
eleganceRouter.post("/elegance/:route", async (req, res) => {
try {
const route = req.params.route as Routes;
const result = await eleganceServerClient.handleRoute(route, req.body);
return res.status(200).json(result);
} catch (error: any) {
return res.status(error.status).json(error);
}
});
- Import the eleganceRouter into the
./server/index.ts
import express from "express";
import { eleganceRouter } from "./routes/elegance";
const app = express();
app.use(eleganceRouter);
app.listen(4000, () => {
console.log(`Server started on port: ${4000}`);
});
- Run your server
- Create a
eleganceClient.ts
file - Import the
createEleganceClient
function from @singlestore/elegance-sdk
import { createEleganceClient } from "@singlestore/elegance-sdk";
export const eleganceClient = createEleganceClient("mysql", {
baseURL: "http://localhost:4000"
});
- Import the
eleganceClient
to your component
import { useEffect } from "react";
import { eleganceClient } from "@/services/eleganceClient";
export function ExampleComponent() {
const query = eleganceClient.hooks.useQuery<{ name: string }[]>({ initialValue: [], initialIsLoading: true });
const { execute: executeQuery } = query;
useEffect(() => {
executeQuery({ query: "SELECT name FROM table LIMIT 3" });
}, [executeQuery]);
if (query.isLoading) return "Loading...";
return (
<div>
{query.value.map(item => (
<h4 key={item.name}>{item.name}</h4>
))}
</div>
);
}
- Run your client
Templates
You can find templates using the Elegance SDK here:
Example apps
You can find example apps using the Elegance SDK here:
API
createEleganceServerClient
Creates an EleganceServerClient instance for a server.
Parameters:
Returns: eleganceServerClient
eleganceServerClient
Server client that includes a database connection, controllers and OpenAI client. It's used on the server to handle requests from the client and execute logic.
eleganceServerClient.connection
MySQL or MongoDB connection to interact with a database
eleganceServerClient.handleRoute
Accepts a route and executes the controller for that route.
Parameters:
route: string
- controller route namebody: object
- controller body
eleganceServerClient.controllers.insertOne.execute<T>
Inserts one record.
Parameters:
body: {
collection: string;
generateId?: boolean;
value: MongoOptionalUnlessRequiredId<T>;
options?: MongoInsertOneOptions;
} | {
table: string;
generateId?: boolean;
value: T;
}
Returns: T
eleganceServerClient.controllers.insertMany.execute<Array<T>>
Inserts many records.
Parameters:
body: {
collection: string;
values: Array<MongoOptionalUnlessRequiredId<T[number]>>;
generateId?: boolean;
options?: MongoBulkWriteOptions;
} | {
table: string;
generateId?: boolean;
values: Array<T>;
}
Returns: Array<T>
eleganceServerClient.controllers.updateMany.execute<Array<T>>
Updates many records.
Parameters:
body: {
collection: string;
filter: MongoFilter<T[number]>;
update: MongoUpdateFilter<T[number]>;
options?: MongoUpdateOptions;
updatedFilter?: MongoFilter<T[number]>;
} | {
table: string;
where: MySQLWhere;
set: MySQLSet;
updatedWhere: MySQLWhere;
}
Returns: Array<T>
eleganceServerClient.controllers.deleteMany.execute<T>
Deletes many records.
Parameters:
body: {
collection: string;
filter: MongoFilter<T>;
options?: MongoDeleteOptions;
} | {
table: string;
where: MySQLWhere;
}
Returns: { message: string }
eleganceServerClient.controllers.findOne.execute<T>
Gets one record.
Parameters:
body: {
collection: string;
filter?: MongoFilter<T>;
options?: MongoFindOptions;
} | {
table: string;
columns?: string[];
where?: MySQLWhere;
}
Returns: T
eleganceServerClient.controllers.findMany.execute<Array<T>>
Gets many records.
Parameters:
body: {
collection: string;
filter?: MongoFilter<T[number]>;
options?: MongoFindOptions;
} | {
table: string;
columns?: string[];
where?: MySQLWhere;
skip?: number;
limit?: number;
}
Returns: Array<object>
eleganceServerClient.controllers.query.execute<Array<T>>
Executes MySQL or aggregate query.
Parameters:
body: {
collection: string;
pipeline: object[];
options?: MongoAggregateOptions;
} | {
query: string;
}
Returns: Array<T>
eleganceServerClient.controllers.createEmbedding.execute
Creates embedding.
Parameters:
body: {
input: string | string[] | object | object[];
}
Returns: Array<number>
eleganceServerClient.controllers.vectorSearch.execute
Performs vector search in the collection based on the query.
Parameters:
body: {
collection: string;
embeddingField: string;
query: string;
limit?: number;
} | {
table: string;
embeddingField: string;
query: string;
limit?: number;
}
Returns: Array<object>
eleganceServerClient.controllers.chatCompletion.execute
Accepts a prompt, performs vector search, and creates chat completion for the found records.
Parameters:
body: {
collection: string;
prompt: string;
model?: string;
textField?: string;
embeddingField?: string;
minSimilarity?: number;
systemRole?: string;
messages?: CreateChatCompletionBody["messages"];
maxTokens?: CreateChatCompletionBody["max_tokens"];
maxContextLength?: number;
temperature?: CreateChatCompletionBody["temperature"];
} | {
table: string;
prompt: string;
model?: string;
textField?: string;
embeddingField?: string;
minSimilarity?: number;
systemRole?: string;
messages?: CreateChatCompletionBody["messages"];
maxTokens?: CreateChatCompletionBody["max_tokens"];
maxContextLength?: number;
temperature?: CreateChatCompletionBody["temperature"];
}
Returns:
{
content: string;
context: string;
}
eleganceServerClient.controllers.createFileEmbeddings.execute
Accepts a CSV or PDF file as a DataURL, splits it into chunks and creates embeddings.
Parameters:
body: {
dataURL: string;
textField?: string;
embeddingField?: string;
chunkSize?: number;
}
Returns: Array<{ text: string; embedding: number[]; }>
eleganceServerClient.controllers.createAndInsertFileEmbeddings.execute
Accepts a CSV or PDF file as a DataURL, splits it into chunks, creates embeddings, and inserts them into a database.
Parameters:
body: {
collection: string;
dataURL: string;
textField?: string;
embeddingField?: string;
chunkSize?: number;
} | {
table: string;
dataURL: string;
textField?: string;
embeddingField?: string;
chunkSize?: number;
}
Returns: Array<{ text: string; embedding: number[]; }>
eleganceServerClient.openai
Default OpenAI client + helpers
eleganceServerClient.openai.helpers.createEmbedding
Creates embedding using the OpenAI Embeddings API
Parameters:
input: string | Array<string> | object | Array<object>
- input value
Returns: Array<number>
eleganceServerClient.openai.helpers.embeddingToBuffer
Converts an embedding into a buffer that is then inserted into the database.
Parameters:
Returns: Buffer
eleganceServerClient.openai.helpers.dataURLtoEmbeddings
Converts a DataURL (csv, pdf) into an embedding by splitting the text into chunks.
Parameters:
Returns: Array<{ text: string; embedding: number[] }>
eleganceServerClient.openai.helpers.createChatCompletion
Generates a chat completion using the OpenAI ChatCompletion API.
Parameters:
options: ChatCompletionCreateParamsBase
Returns: string
createEleganceClient
Creates an EleganceClient instance for a client.
Parameters:
Returns: eleganceServerClient
eleganceClient
Client that includes requests and hooks. It is used to make requests to the server.
eleganceClient.requests
Clean functions to make requests to the server. They can be used anywhere within a project and are handled like typical async functions. The parameters for each request correspond to the controller parameters by name. To familiarize with the parameters, refer to the eleganceServerClient.controllers.<requestName>.execute
section.
eleganceClient.hooks
Ready-to-use React.js hooks with state handlers that use requests. Each hook has the following type:
<R = any,>(options?: { initialValue?: R; initialIsLoading?: boolean; onError?: (error: DefaultError) => void }) => {
value: R | undefined;
error: DefaultError | undefined;
isLoading: boolean;
setValue: react.Dispatch<react.SetStateAction<Awaited<R> | undefined>>;
setError: react.Dispatch<react.SetStateAction<DefaultError | undefined>>;
setIsLoading: react.Dispatch<react.SetStateAction<boolean>>;
execute: (body: object) => Promise<Awaited<R> | undefined>;
};
License
Apache 2.0
© 2023 SingleStore