@trubrics/trubrics
Version:
A Trubrics SDK for JavaScript applications
99 lines (98 loc) • 4.04 kB
JavaScript
import { MAX_FLUSH_BATCH_SIZE } from "./config.js";
export const validateResponse = (response) => {
if (!response.ok) {
console.error(`Request failed: ${response.statusText}`);
return false;
}
return true;
};
export const validateRequest = (strings, numbers, dates, mandatory) => {
if (mandatory.some(item => item === null || item === undefined)) {
throw new Error("Mandatory fields cannot be null or undefined");
}
for (const item of strings) {
if (item !== null && item !== undefined && (typeof item !== "string" || item === "")) {
throw new Error("String fields must be non-empty strings");
}
}
for (const item of numbers) {
if (item !== null && item !== undefined && (!Number.isInteger(item) || typeof item !== "number")) {
throw new Error("Integer fields must be integers");
}
}
for (const item of dates) {
if (item !== null && item !== undefined && !(item instanceof Date)) {
throw new Error("Datetime fields must be instances of Date");
}
}
};
export const checkAuth = (apiKey) => {
if (!apiKey) {
throw new Error("No API key provided.");
}
};
export const flushQueue = async (queue, host, apiKey, isVerbose) => {
const events = [];
const llmEvents = [];
const queueCount = queue.length;
if (queueCount === 0) {
return;
}
const numberOfEventsToPublish = queueCount < MAX_FLUSH_BATCH_SIZE ? queueCount : MAX_FLUSH_BATCH_SIZE;
const eventsToPublish = queue.slice(0, numberOfEventsToPublish);
for (const event of eventsToPublish) {
if (event.eventType === TrubricsEventTypes.EVENT) {
events.push(event.event);
}
else if (event.eventType === TrubricsEventTypes.LLM_EVENT) {
llmEvents.push(event.event);
}
}
const eventsSuccess = await batchEvents(events, host, apiKey, isVerbose, TrubricsIngestionEndpoints.EVENT, TrubricsEventTypes.EVENT);
const llmEventsSuccess = await batchEvents(llmEvents, host, apiKey, isVerbose, TrubricsIngestionEndpoints.LLM_EVENT, TrubricsEventTypes.LLM_EVENT);
if (!eventsSuccess) {
await retryBatch(events, host, apiKey, isVerbose, TrubricsIngestionEndpoints.EVENT, TrubricsEventTypes.EVENT);
}
if (!llmEventsSuccess) {
await retryBatch(llmEvents, host, apiKey, isVerbose, TrubricsIngestionEndpoints.LLM_EVENT, TrubricsEventTypes.LLM_EVENT);
}
queue.splice(0, numberOfEventsToPublish);
};
const retryBatch = async (events, host, apiKey, isVerbose, endpoint, eventType) => {
await new Promise(resolve => setTimeout(resolve, 5000));
if (isVerbose) {
console.info(`Retrying to post ${events.length} ${eventType}s`);
}
await batchEvents(events, host, apiKey, isVerbose, endpoint, eventType);
};
const batchEvents = async (events, host, apiKey, isVerbose, endpoint, eventType) => {
if (!events.length) {
return true;
}
if (isVerbose) {
console.info(`Posting ${events.length} ${eventType}s`);
}
try {
const url = new URL(`${host}/${endpoint}`);
const response = await fetch(url, {
method: "POST",
body: JSON.stringify(events),
headers: { "Content-Type": "application/json", "x-api-key": apiKey }
});
return validateResponse(response);
}
catch (error) {
console.error(`Trubrics was unable to post ${events.length} ${eventType}s.`, error);
return false;
}
};
export var TrubricsEventTypes;
(function (TrubricsEventTypes) {
TrubricsEventTypes["EVENT"] = "event";
TrubricsEventTypes["LLM_EVENT"] = "llm_event";
})(TrubricsEventTypes || (TrubricsEventTypes = {}));
export var TrubricsIngestionEndpoints;
(function (TrubricsIngestionEndpoints) {
TrubricsIngestionEndpoints["EVENT"] = "publish_events";
TrubricsIngestionEndpoints["LLM_EVENT"] = "publish_llm_events";
})(TrubricsIngestionEndpoints || (TrubricsIngestionEndpoints = {}));