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.
- Dot product 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
npm install @singlestore/elegance-sdk
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: "<DB_HOST>"
user: "<DB_USER>"
password: "<DB_PASSWORD>"
database: "<DB_NAME>"
},
ai: {
openai: {
apiKey: "<OPENAI_API_KEY>"
}
}
});
In case if you don't want to use OpenAI, you can replace the existing AI SDK logic with customizers:
...
import {
EmbeddingInput,
CreateEmbeddingResult,
CreateChatCompletionParams,
CreateChatCompletionResult
} from "@singlestore/elegance-sdk/types";
...
ai: {
customizers: {
createEmbedding: async (input: EmbeddingInput): Promise<CreateEmbeddingResult> => {
const embedding = await customFn(input);
return embedding;
},
createChatCompletion: async (params: CreateChatCompletionParams): Promise<CreateChatCompletionResult> => {
const chatCompletion = await customFn(params);
return chatCompletion;
}
}
}
...
- 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 the 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
You can find templates using the Elegance SDK here:
You can find example apps using the Elegance SDK here:
Creates an EleganceServerClient instance for a server.
Parameters:
connectionType: "kai" | "mysql"
-
config: { connection: KaiConnectionConfig | MySQLConnectionConfig; ai?: { openai?: OpenAIConfig; customizers?: { createEmbedding?: (input: EmbeddingInput) => Promise<CreateEmbeddingResult>; createChatCompletion?: (params: CreateChatCompletionParams) => Promise<CreateChatCompletionResult>; } // You can use your own functions to create an embedding or a chat completion. }; }
Returns: eleganceServerClient
Server client that includes a database connection, controllers and AI client. It's used on the server to handle requests from the client and execute logic.
MySQL or MongoDB connection to interact with a database
Accepts a route and executes the controller for that route.
Parameters:
-
route: string
- controller route name -
body: object
- controller body
Inserts one record.
Parameters:
Kai
body: {
db?: string;
collection: string;
generateId?: boolean;
value: MongoOptionalUnlessRequiredId<T>;
options?: MongoInsertOneOptions;
}
MySQL
body: {
db?: string;
collection: string;
generateId?: boolean;
value: T;
}
Returns: T
Inserts many records.
Parameters:
Kai
body: {
db?: string;
collection: string;
values: Array<MongoOptionalUnlessRequiredId<T[number]>>;
generateId?: boolean;
options?: MongoBulkWriteOptions;
}
MySQL
body: {
db?: string;
collection: string;
generateId?: boolean;
values: Array<T>;
}
Returns: Array<T>
Updates many records.
Parameters:
Kai
body: {
db?: string;
collection: string;
filter: MongoFilter<T[number]>;
update: MongoUpdateFilter<T[number]>;
options?: MongoUpdateOptions;
updatedFilter?: MongoFilter<T[number]>;
}
MySQL
body: {
db?: string;
collection: string;
where: MySQLWhere;
set: MySQLSet;
updatedWhere: MySQLWhere;
}
Returns: Array<T>
Deletes many records.
Parameters:
Kai
body: {
db?: string;
collection: string;
filter: MongoFilter<T>;
options?: MongoDeleteOptions;
}
MySQL
body: {
db?: string;
collection: string;
where: MySQLWhere;
}
Returns: { message: string }
Gets one record.
Parameters:
Kai
body: {
db?: string;
collection: string;
filter?: MongoFilter<T>;
options?: MongoFindOptions;
}
MySQL
body: {
db?: string;
collection: string;
columns?: string[];
where?: MySQLWhere;
extra?: string;
}
Returns: T
Gets many records.
Parameters: Kai
body: {
db?: string;
collection: string;
filter?: MongoFilter<T[number]>;
options?: MongoFindOptions;
}
MySQL
body: {
db?: string;
collection: string;
columns?: string[];
where?: MySQLWhere;
skip?: number;
limit?: number;
extra?: string;
}
Returns: Array<object>
Executes MySQL or aggregate query.
Parameters:
Kai
body: {
db?: string;
collection: string;
query: object[];
options?: MongoAggregateOptions;
}
MySQL
body: {
query: string;
}
Returns: Array<T>
Creates embedding.
Parameters:
body: {
input: string | string[] | object | object[];
}
Returns: Embedding
Accepts a CSV or PDF file, splits it into chunks and creates embeddings.
Parameters:
body: {
dataURL: string;
textField?: string;
embeddingField?: string;
chunkSize?: number;
}
Returns: Array<{ text: string; embedding: Embedding; }>
Accepts a CSV or PDF file, splits it into chunks, creates embeddings, and inserts them into a database.
Parameters:
body: {
db?: string;
collection: string;
dataURL: string;
textField?: string;
embeddingField?: string;
chunkSize?: number;
}
Returns: Array<{ text: string; embedding: Embedding; }>
Accepts a prompt and creates chat completion.
Parameters:
body: {
model?: ChatCompletionCreateParamsNonStreaming["model"];
prompt?: string;
systemRole?: string;
messages?: ChatCompletionMessage[];
temperature?: number;
maxTokens?: number;
}
Returns:
string | null;
Accepts a prompt, performs dot product search, and creates chat completion for the found records.
Parameters:
body: {
db?: string;
collection: string;
model?: ChatCompletionCreateParamsNonStreaming["model"];
prompt: string;
systemRole?: string;
messages?: ChatCompletionMessage[];
temperature?: number;
maxTokens?: number;
textField?: string;
embeddingField?: string;
minSimilarity?: number;
maxContextLength?: number;
}
Returns:
{
content: string;
context: string;
}
Performs dot product search in the collection based on the query.
Parameters:
body: {
db?: string;
collection: string;
query: string;
queryEmbedding?: Embedding;
embeddingField: string;
limit?: number;
minSimilarity?: number;
includeEmbedding?: boolean;
}
Returns: Array<any>
Creates embedding
Parameters:
input: string | Array<string> | object | Array<object>
Returns: Embedding
Converts an embedding into a buffer that is then inserted into the database (for Kai).
Parameters:
embedding: Embedding
Returns: Buffer
Converts text into embeddings by splitting the text into chunks.
Parameters:
text: string
-
options?: { chunkSize?: number; textField?: string; embeddingField?: string; }
Converts a DataURL (csv, pdf) into an embedding by splitting the text into chunks.
Parameters:
dataURL: string
-
options?: { chunkSize?: number; textField?: string; embeddingField?: string; }
Returns: Array<{ text: string; embedding: Embedding }>
Creates a chat completion.
Parameters:
-
params: { model?: ChatCompletionCreateParamsNonStreaming["model"]; prompt?: string; systemRole?: string; messages?: ChatCompletionMessage[]; temperature?: number; maxTokens?: number; }
Returns: string
Creates an EleganceClient instance for a client.
Parameters:
connectionType: "kai" | "mysql"
-
config: { baseURL: string; }
Returns: eleganceServerClient
Client that includes requests and hooks. It is used to make requests to the server.
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>
section.
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>;
};
© 2023 SingleStore