Skip to content
ferroseekdocumentation homemain, packages at version v0.1.0
Ferroseek on GitHub

Library API

Two TypeScript packages live in this repository. They are workspace packages, not published to npm; see Embed the engine in a Worker for how to depend on them.

Package Directory Purpose
@ferroseek/engine packages/ferroseek/ The WebAssembly engine and its loader, auth and response handling
@ferroseek/client packages/search-client/ The official Elasticsearch client, connected by settings only
function createFerroseek(options: FerroseekOptions): Ferroseek;
interface FerroseekOptions {
readonly wasm: WebAssembly.Module;
readonly source: IndexSource;
readonly auth?: AuthConfig;
readonly diagnostics?: boolean;
readonly onError?: (error: unknown, phase: "load" | "request") => void;
}
interface Ferroseek {
fetch(request: Request): Promise<Response>;
ready(): Promise<LoadStats>;
}
interface LoadStats {
readonly loadMs: number;
readonly indexBytes: number;
readonly docCount: number;
}

fetch answers the Elasticsearch routes listed in Routes. It loads the index on first use; concurrent first calls share one load, and a failed load is retried by the next call. When auth is set, requests are checked before anything else. Request bodies are read with a 256 KiB cap and never buffered beyond it.

ready() loads the index now and resolves with its statistics.

import wasm from "@ferroseek/engine/wasm";

The compiled engine as a WebAssembly.Module, for Wrangler’s CompiledWasm rule. It is a separate entry point so that the main entry stays importable in Node and in tests. The file it imports, packages/ferroseek/wasm/ferroseek.wasm, is produced by npm run wasm:build.

interface IndexSource {
readonly description: string;
manifest(): Promise<unknown>;
part(file: string): Promise<ReadableStream<Uint8Array>>;
}
function assetsIndexSource(assets: AssetsFetcher, basePath?: string): IndexSource;
interface AssetsFetcher {
fetch(request: Request): Promise<Response>;
}

assetsIndexSource(env.ASSETS, "index") reads index/manifest.json and the part files through a Workers static-assets binding. basePath defaults to "index" and may only contain letters, digits, ., _, - and /. The loader validates the manifest, then streams each part into WebAssembly memory at its offset and checks its length.

interface AuthSettings {
readonly username?: string;
readonly password?: string;
readonly apiKey?: string; // base64("id:api_key")
}
interface AuthConfig {
readonly basic?: { readonly username: string; readonly password: string };
readonly apiKey?: { readonly id: string; readonly key: string };
}
function authFromEnv(env: Readonly<Record<string, unknown>>): AuthConfig | undefined;
function parseAuth(settings: AuthSettings, labels?: Readonly<Record<keyof AuthSettings, string>>): AuthConfig;
function checkAuth(request: Request, config: AuthConfig): Promise<Response | null>;

authFromEnv reads FERROSEEK_USERNAME, FERROSEEK_PASSWORD and FERROSEEK_API_KEY, and returns undefined when none is set. parseAuth validates settings and throws FerroseekConfigError on an inconsistent combination. checkAuth returns null for an authenticated request, otherwise the 401 response to send.

Thrown when the engine is configured inconsistently: missing or malformed settings.

function createSearchClient(config: SearchClientConfig): SearchClient; // the @elastic/elasticsearch Client
interface SearchClientConfig {
readonly node: SearchNode;
readonly auth?: SearchAuth;
readonly options?: SearchClientOptions;
}
type SearchNode = string | URL | InProcessNode;
interface InProcessNode {
fetch(request: Request): Promise<Response>;
}
type SearchAuth =
| { readonly username: string; readonly password: string }
| { readonly apiKey: string };

SearchClientOptions is the official client’s ClientOptions without node, nodes, auth, Connection, cloud and ConnectionPool.

function searchConfigFromEnv(
env: Readonly<Record<string, unknown>>,
embedded: () => InProcessNode,
): ResolvedSearchConfig;
interface ResolvedSearchConfig {
readonly mode: SearchMode; // "embedded" | "remote"
readonly config: SearchClientConfig;
}

Reads SEARCH_URL, SEARCH_USERNAME, SEARCH_PASSWORD and SEARCH_API_KEY. embedded is called only when SEARCH_URL is unset. See Connect with the client.

  • SearchConfigError: thrown for missing, malformed or inconsistent connection settings.
  • errors: the official client’s error classes (ResponseError, ConnectionError, TimeoutError, …).
  • estypes: the official client’s request and response types.