API Reference
This is a comprehensive reference for @514labs/moose-lib, detailing all exported components, types, and utilities.
Core Types
Key
A type for marking fields as primary keys in data models.
// Exampleinterface MyModel { id: Key<string>; // Marks 'id' as a primary key of type string}JWT
A type for working with JSON Web Tokens.
// Exampletype UserJWT = JWT<{ userId: string, role: string }>;ApiUtil
Interface providing utilities for analytics APIs.
interface ApiUtil { client: MooseClient; // Client for interacting with the database sql: typeof sql; // SQL template tag function jwt: JWTPayload | undefined; // Current JWT if available}BaseModel
Not applicable in TypeScript - use TypeScript interfaces instead.
MooseClient
Client for interacting with ClickHouse and Temporal.
class MooseClient { query: QueryClient; // For database queries workflow: WorkflowClient; // For workflow operations}ApiResult
Not applicable in TypeScript - APIs return values directly.
Configuration Types
OlapConfig / BaseOlapConfig
Base configuration interface for OlapTable with common table configuration options.
interface BaseOlapConfig<T> { // Optional database name (defaults to moose.config.toml clickhouse_config.db_name) database?: string; // Optional array of field names to order by orderByFields?: (keyof T & string)[]; // Optional SQL expression for ORDER BY clause (alternative to orderByFields) orderByExpression?: string; // Optional table engine (defaults to MergeTree) engine?: ClickHouseEngines; // Optional settings for table configuration settings?: { [key: string]: string }; // Optional secondary/data-skipping indexes indexes?: TableIndex[]; // Optional projections for alternative data ordering within parts projections?: TableProjection[]; // Optional lifecycle mode (defaults to MOOSE_MANAGED) lifeCycle?: LifeCycle; // Per-table filter applied during `moose seed clickhouse` seedFilter?: { limit?: number; where?: string }; // Additional engine-specific fields (ver, isDeleted, keeperPath, etc.) // depend on the engine type}Infrastructure Components
OlapTable
Creates a ClickHouse table with the schema of type T.
// Basic usage with MergeTree (default)export const myTable = new OlapTable<UserProfile>("user_profiles"); // With sorting configuration (fields)export const myConfiguredTable = new OlapTable<UserProfile>("user_profiles", { orderByFields: ["id", "timestamp"]}); // With sorting configuration (expression)export const myConfiguredTableExpr = new OlapTable<UserProfile>("user_profiles_expr", { // Equivalent to orderByFields: ["id", "timestamp"] orderByExpression: "(id, timestamp)"}); // Disable sorting entirelyexport const myUnsortedTable = new OlapTable<UserProfile>("user_profiles_unsorted", { orderByExpression: "tuple()"}); // For deduplication, explicitly set the ReplacingMergeTree engineexport const dedupTable = new OlapTable<UserProfile>("user_profiles", { engine: ClickHouseEngines.ReplacingMergeTree, orderByFields: ["id", "timestamp"], ver: "updated_at", // Optional: version column for keeping latest isDeleted: "deleted" // Optional: soft delete marker (requires ver)});Stream
Creates a Redpanda topic with the schema of type T.
// Basic usageexport const myStream = new Stream<UserEvent>("user_events"); // With configurationexport const myConfiguredStream = new Stream<UserEvent>("user_events", { parallelism: 3, retentionPeriod: 86400 // 1 day in seconds}); // Adding transformationsmyConfiguredStream.addTransform( destinationStream, (record) => transformFunction(record));IngestApi
Creates an HTTP endpoint for ingesting data of type T.
// Basic usage with destination streamexport const myIngestApi = new IngestApi<UserEvent>("user_events", { destination: myUserEventStream});Api
Creates an HTTP endpoint for querying data with request type T and response type R.
// Basic usageexport const myApi = new Api<UserQuery, UserProfile[]>( "getUserProfiles", async (params, { client, sql }) => { const result = await client.query.execute( sql.statement`SELECT * FROM user_profiles WHERE age > ${params.minAge} LIMIT 10` ); return result; });IngestPipeline
Combines ingest API, stream, and table creation in a single component.
// Basic usageexport const pipeline = new IngestPipeline<UserEvent>("user_pipeline", { ingestApi: true, stream: true, table: true}); // With advanced configurationexport const advancedPipeline = new IngestPipeline<UserEvent>("advanced_pipeline", { ingestApi: true, stream: { parallelism: 3 }, table: { orderByFields: ["id", "timestamp"] }});MaterializedView
Creates a materialized view in ClickHouse.
// Basic usageexport const view = new MaterializedView<UserStatistics>({ selectStatement: "SELECT user_id, COUNT(*) as event_count FROM user_events GROUP BY user_id", tableName: "user_events", materializedViewName: "user_statistics", orderByFields: ["user_id"]});View
Creates a standard SQL view in ClickHouse. Views are read-time projections defined by a SELECT statement over one or more base tables or other views.
// Basic usageexport const activeUserEvents = new View( "active_user_events", sql.statement` SELECT ${events.columns.id} AS event_id, ${users.columns.id} AS user_id, ${users.columns.name} AS user_name, ${events.columns.ts} AS ts FROM ${events} JOIN ${users} ON ${events.columns.user_id} = ${users.columns.id} WHERE ${users.columns.active} = 1 `, [events, users]);Note: Use View for read-time projections. For write-time transformations with separate storage, use MaterializedView instead.
SQL Utilities
sql Template Tag
Template tag for creating type-safe SQL queries with parameters. Use sql.statement for complete SQL statements and sql.fragment for partial SQL (expressions, conditions, clauses).
import { sql } from "@514labs/moose-lib"; // sql.statement — for complete SQL queriesconst query = sql.statement` SELECT * FROM users WHERE age > ${minAge} AND country = ${country} LIMIT ${limit}`; // sql.fragment — for partial SQL (conditions, expressions, clauses)const condition = sql.fragment`age > ${minAge} AND country = ${country}`;const fullQuery = sql.statement`SELECT * FROM users WHERE ${condition}`; // sql.join — join an array of Sql fragments with a separatorconst conditions = [ sql.fragment`age > ${minAge}`, sql.fragment`country = ${country}`,];const joined = sql.statement`SELECT * FROM users WHERE ${sql.join(conditions, "AND")}`; // sql.raw — inject raw SQL strings (⚠️ SQL injection risk with untrusted input)const tableName = sql.raw("users");const rawQuery = sql.statement`SELECT * FROM ${tableName}`;| Tag | isFragment | Use for |
|---|---|---|
sql.statement | false | Complete queries (SELECT, INSERT, CREATE, etc.) |
sql.fragment | true | Partial SQL (expressions, conditions, clauses) |
sql (deprecated) | undefined | Legacy usage — migrate to sql.statement or sql.fragment |
All three produce the same Sql object. The isFragment property is metadata that enables the Moose Language Server to validate statements while skipping fragments.
ClickHouse Utilities
ClickHouseEngines Enum
Available table engines:
enum ClickHouseEngines { MergeTree = "MergeTree", ReplacingMergeTree = "ReplacingMergeTree", AggregatingMergeTree = "AggregatingMergeTree", SummingMergeTree = "SummingMergeTree", ReplicatedMergeTree = "ReplicatedMergeTree", ReplicatedReplacingMergeTree = "ReplicatedReplacingMergeTree", ReplicatedAggregatingMergeTree = "ReplicatedAggregatingMergeTree", ReplicatedSummingMergeTree = "ReplicatedSummingMergeTree", S3Queue = "S3Queue"}ReplacingMergeTreeConfig
Configuration for ReplacingMergeTree tables:
type ReplacingMergeTreeConfig<T> = { engine: ClickHouseEngines.ReplacingMergeTree; orderByFields?: (keyof T & string)[]; ver?: keyof T & string; // Optional: version column for keeping latest isDeleted?: keyof T & string; // Optional: soft delete marker (requires ver) settings?: { [key: string]: string };}Replicated Engine Configurations
Configuration for replicated table engines:
// ReplicatedMergeTreetype ReplicatedMergeTreeConfig<T> = { engine: ClickHouseEngines.ReplicatedMergeTree; keeperPath?: string; // Optional: ZooKeeper/Keeper path (omit for Cloud) replicaName?: string; // Optional: replica name (omit for Cloud) orderByFields?: (keyof T & string)[]; settings?: { [key: string]: string };} // ReplicatedReplacingMergeTreetype ReplicatedReplacingMergeTreeConfig<T> = { engine: ClickHouseEngines.ReplicatedReplacingMergeTree; keeperPath?: string; // Optional: ZooKeeper/Keeper path (omit for Cloud) replicaName?: string; // Optional: replica name (omit for Cloud) ver?: keyof T & string; // Optional: version column isDeleted?: keyof T & string; // Optional: soft delete marker orderByFields?: (keyof T & string)[]; settings?: { [key: string]: string };} // ReplicatedAggregatingMergeTreetype ReplicatedAggregatingMergeTreeConfig<T> = { engine: ClickHouseEngines.ReplicatedAggregatingMergeTree; keeperPath?: string; // Optional: ZooKeeper/Keeper path (omit for Cloud) replicaName?: string; // Optional: replica name (omit for Cloud) orderByFields?: (keyof T & string)[]; settings?: { [key: string]: string };} // ReplicatedSummingMergeTreetype ReplicatedSummingMergeTreeConfig<T> = { engine: ClickHouseEngines.ReplicatedSummingMergeTree; keeperPath?: string; // Optional: ZooKeeper/Keeper path (omit for Cloud) replicaName?: string; // Optional: replica name (omit for Cloud) columns?: string[]; // Optional: columns to sum orderByFields?: (keyof T & string)[]; settings?: { [key: string]: string };}Note: The keeperPath and replicaName parameters are optional. When omitted, Moose uses smart defaults that work in both ClickHouse Cloud and self-managed environments (default path: /clickhouse/tables/{uuid}/{shard} with replica {replica}). You can still provide both parameters explicitly if you need custom replication paths.
Task Management
Task
A class that represents a single task within a workflow system.
// No input, no outputexport const task1 = new Task<null, void>("task1", { run: async () => { console.log("No input/output"); }, retries: 3, timeout: "30s"}); // With input and outputexport const task2 = new Task<InputType, OutputType>("task2", { run: async (ctx) => { return process(ctx.input); }, onComplete: [nextTask]});TaskConfig
Configuration options for tasks.
interface TaskConfig<T, R> { // The main function that executes the task logic run: (context: TaskContext<T>) => Promise<R>; // Optional array of tasks to execute after this task completes onComplete?: (Task<R extends void ? null : R, any> | Task<R extends void ? null : R, void>)[]; // Optional function that is called when the task is cancelled. onCancel?: (context: TaskContext<T>) => Promise<void>; // Optional timeout duration (e.g., "30s", "5m", "never") timeout?: string; // Optional number of retry attempts retries?: number;}Workflow
A class that represents a complete workflow composed of interconnected tasks.
const myWorkflow = new Workflow("getData", { startingTask: callAPI, schedule: "@every 5s", // Run every 5 seconds timeout: "1h", retries: 3});WorkflowConfig
Configuration options for defining a workflow.
interface WorkflowConfig { // The initial task that begins the workflow execution startingTask: Task<null, any> | Task<null, void> | Task<any, any> | Task<any, void>; // Optional number of retry attempts retries?: number; // Optional timeout duration (e.g., "10m", "1h", "never") timeout?: string; // Optional cron-style schedule string schedule?: string;}Export Required
Ensure your Infrastructure Components is correctly exported from your app/index.ts file.
Example: export { myTable, myStream, myApi, myWorkflow, myTask, myPipeline, myMaterializedView, myView }
Learn more about export pattern: local development / hosted.
Important: The following components must be exported from your app/index.ts (TypeScript) or imported into main.py (Python) for Moose to detect them:
OlapTableinstancesStreaminstancesIngestApiinstancesApiinstancesIngestPipelineinstancesMaterializedViewinstancesViewinstancesTaskinstancesWorkflowinstances
Configuration objects and utilities (like DeadLetterQueue, Key, sql) do not need to be exported as they are used as dependencies of the main components.