@llamaindex/env
Version:
environment wrapper, supports all JS environment including node, deno, bun, edge runtime, and cloudflare worker
166 lines (158 loc) • 5.99 kB
JavaScript
export { ok } from 'node:assert';
import { createHash } from 'node:crypto';
export { randomUUID } from 'node:crypto';
export { EOL } from 'node:os';
export { default as path } from 'node:path';
export { Readable } from 'node:stream';
export { fileURLToPath } from 'node:url';
export { createWriteStream } from 'node:fs';
export { default as fs } from 'node:fs/promises';
export { AsyncLocalStorage } from 'node:async_hooks';
class NotSupportCurrentRuntimeClass {
constructor(runtime){
throw new Error(`Current environment ${runtime} is not supported`);
}
static bind(runtime) {
return class extends NotSupportCurrentRuntimeClass {
constructor(...args){
super(runtime);
}
};
}
}
// This is a workaround for the lack of globalThis in some environments
// It's being used across multiple places inside the `env` package
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const glo = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {};
const importIdentifier = "__ $@llamaindex/env$ __";
if (glo[importIdentifier] === true) {
/**
* Dear reader of this message. Please take this seriously.
*
* If you see this message, make sure that you only import one version of llamaindex. In many cases,
* your package manager installs two versions of llamaindex that are used by different packages within your project.
* Another reason for this message is that some parts of your project use the CJS version of llamaindex
* and others use the ESM version of llamaindex.
*
* This often leads to issues that are hard to debug. We often need to perform constructor checks,
* e.g. `node instanceof TextNode`. If you imported different versions of llamaindex, it is impossible for us to
* do the constructor checks anymore - which might break the functionality of your application.
*/ console.error("llamaindex was already imported. This breaks constructor checks and will lead to issues!");
}
glo[importIdentifier] = true;
function noop() {}
const emptyLogger = Object.freeze({
log: noop,
error: noop,
warn: noop
});
const consoleLogger = Object.freeze({
log: console.log.bind(console),
error: console.error.bind(console),
warn: console.warn.bind(console)
});
/**
* Converts a Uint8Array to a base64 string.
* For large arrays, it processes the data in chunks to avoid memory issues.
* Falls back to Buffer if available for better performance.
*
* @param bytes - The Uint8Array to convert
* @returns The base64 string representation
*/ function uint8ArrayToBase64(bytes) {
// Use Buffer if available (Node.js environment)
if (typeof Buffer !== "undefined") {
return Buffer.from(bytes).toString("base64");
}
// For browsers and other environments without Buffer
// Process in chunks for large arrays to avoid memory issues
const CHUNK_SIZE = 32768; // 32KB chunks
let result = "";
// For small arrays, use the built-in btoa function directly
if (bytes.length < CHUNK_SIZE) {
const binary = Array.from(bytes).map((byte)=>String.fromCharCode(byte)).join("");
return globalThis.btoa(binary);
}
// For large arrays, process in chunks
for(let i = 0; i < bytes.length; i += CHUNK_SIZE){
const chunk = bytes.subarray(i, i + CHUNK_SIZE);
const binary = Array.from(chunk).map((byte)=>String.fromCharCode(byte)).join("");
result += globalThis.btoa(binary);
}
return result;
}
// DO NOT EXPOSE THIS VARIABLE TO PUBLIC, IT IS USED INTERNALLY FOR CLOUDFLARE WORKER
const INTERNAL_ENV = {};
/**
* Set environment variables before using llamaindex, because some LLM need to access API key before running.
*
* You have to set the environment variables in Cloudflare Worker environment,
* because it doesn't have any global environment variables.
*
* @example
* ```ts
* export default {
* async fetch(
* request: Request,
* env: Env,
* ctx: ExecutionContext,
* ): Promise<Response> {
* const { setEnvs } = await import("@llamaindex/env");
* setEnvs(env);
* // ...
* return new Response("Hello, World!");
* },
* };
* ```
*
* @param envs Environment variables
*/ function setEnvs(envs) {
Object.assign(INTERNAL_ENV, envs);
}
function getEnv(name) {
if (INTERNAL_ENV[name]) {
return INTERNAL_ENV[name];
}
if (typeof process === "undefined" || typeof process.env === "undefined") {
// @ts-expect-error Deno is not defined
if (typeof Deno === "undefined") {
throw new Error("Current environment is not supported");
} else {
// @ts-expect-error Deno is not defined
return Deno.env.get(name);
}
}
return process.env[name];
}
// Node.js 18 doesn't have CustomEvent by default
// Refs: https://github.com/nodejs/node/issues/40678
// eslint-disable-next-line @typescript-eslint/no-explicit-any
class CustomEvent extends Event {
#detail;
get detail() {
return this.#detail;
}
constructor(event, options){
super(event, options);
this.#detail = options?.detail;
}
/**
* @deprecated This method is not supported
*/ initCustomEvent() {
throw new Error("initCustomEvent is not supported");
}
}
const defaultCustomEvent = // eslint-disable-next-line @typescript-eslint/no-explicit-any
globalThis.CustomEvent || CustomEvent;
function createSHA256() {
const hash = createHash("sha256");
return {
update (data) {
hash.update(data);
},
digest () {
return hash.digest("base64");
}
};
}
const process$1 = globalThis.process;
export { defaultCustomEvent as CustomEvent, NotSupportCurrentRuntimeClass, consoleLogger, createSHA256, emptyLogger, getEnv, process$1 as process, setEnvs, uint8ArrayToBase64 };