Node.js Client
Zero runtime dependencies. Uses native fetch (Node 18+). Full TypeScript types included. ESM and CJS exports.
Install
npm install wirelogQuick start
import { WireLog } from "wirelog";
const wl = new WireLog({ apiKey: "sk_your_secret_key", host: "https://yourhost.com" });
await wl.track({ event_type: "page_view", user_id: "alice" });
const result = await wl.query("page_view | last 7d | count by user_id");console.log(result);Constructor
new WireLog(config?: WireLogConfig)interface WireLogConfig { apiKey?: string; // Falls back to WIRELOG_API_KEY env var host?: string; // Falls back to WIRELOG_HOST env var or https://api.wirelog.ai}Types
interface TrackEvent { event_type: string; // Required user_id?: string; device_id?: string; session_id?: string; time?: string; // RFC 3339. Auto-generated if omitted event_properties?: Record<string, unknown>; user_properties?: Record<string, unknown>; insert_id?: string; // Auto-generated (randomUUID) if omitted}
interface TrackResult { accepted: number;}
interface IdentifyParams { user_id: string; // Required device_id?: string; user_properties?: Record<string, unknown>; user_property_ops?: { $set?: Record<string, unknown>; $set_once?: Record<string, unknown>; $add?: Record<string, number>; $unset?: string[]; };}
interface IdentifyResult { ok: boolean;}
interface QueryOptions { format?: "llm" | "json" | "csv"; limit?: number; // Default 100, max 10,000 offset?: number;}Methods
track()
wl.track(event: TrackEvent): Promise<TrackResult>Track a single event. Auto-generates insert_id (randomUUID) and time (new Date().toISOString()) if not provided.
await wl.track({ event_type: "purchase", user_id: "u_123", event_properties: { plan: "pro", amount: 49 },});// { accepted: 1 }trackBatch()
wl.trackBatch(events: TrackEvent[]): Promise<TrackResult>Track up to 2000 events in one request.
await wl.trackBatch([ { event_type: "page_view", user_id: "u_1", event_properties: { page: "/" } }, { event_type: "click", user_id: "u_1", event_properties: { button: "cta" } },]);// { accepted: 2 }query()
wl.query(q: string, opts?: QueryOptions): Promise<unknown>Run a pipe DSL query. Returns a Markdown string (llm), parsed JSON (json), or CSV string (csv).
// Markdown table (default)const md = await wl.query("* | last 30d | count by event_type | top 10");
// JSONconst data = await wl.query("page_view | last 7d | count", { format: "json" });
// CSV with paginationconst csv = await wl.query("* | last 90d | count by event_type", { format: "csv", limit: 10000,});identify()
wl.identify(params: IdentifyParams): Promise<IdentifyResult>Bind device_id to user_id and upsert user profile properties. No event emitted.
await wl.identify({ user_id: "alice@acme.org", device_id: "dev_abc", user_properties: { email: "alice@acme.org" }, user_property_ops: { $set: { plan: "enterprise" }, $set_once: { signup_source: "ads" }, $add: { login_count: 1 }, $unset: ["legacy_flag"], },});// { ok: true }Error handling
Non-2xx responses throw WireLogError.
import { WireLog, WireLogError } from "wirelog";
const wl = new WireLog();
try { await wl.track({ event_type: "test" });} catch (e) { if (e instanceof WireLogError) { console.error(e.status); // HTTP status code console.error(e.message); // "WireLog API 401: ..." }}