Complete reference documentation for the SchoBase TypeScript SDK. All methods are fully typed with compile-time safety.
Install SchoBase via npm, yarn, or pnpm:
npm install schobaseInitialize a SchoBase client instance.
function createClient<TSchema extends Schema>(
config: ClientConfig<TSchema>
): SchoBaseClient<TSchema>| Name | Type | Description |
|---|---|---|
| config.endpoint | string | SchoBase server endpoint URL |
| config.apiKey | string | API authentication key |
| config.schema | TSchema | Database schema definition |
| config.timeout? | number | Request timeout in milliseconds (default: 30000) |
import { createClient, defineSchema } from 'schobase'
import { z } from 'zod'
const schema = defineSchema({
tables: {
sensorReadings: {
validator: z.object({
sensorId: z.string(),
timestamp: z.date(),
temperature: z.number(),
}),
timeIndex: 'timestamp',
},
},
})
const client = createClient({
endpoint: process.env.SCHOBASE_ENDPOINT!,
apiKey: process.env.SCHOBASE_API_KEY!,
schema,
})SchoBase supports multiple time series backends. Choose the one that fits your deployment needs: cloud-managed (Timestream), self-hosted (TimescaleDB), or specialized time series (InfluxDB).
PostgreSQL extension optimized for time series data. Best for on-premise deployments and when you need SQL compatibility.
import { createClient, defineSchema } from 'schobase'
import { z } from 'zod'
const schema = defineSchema({
tables: {
temperatures: {
validator: z.object({
sensorId: z.string(),
timestamp: z.date(),
temperature: z.number(),
location: z.string(),
}),
timeIndex: 'timestamp',
},
},
})
const client = await createClient({
backend: 'timescaledb',
schema,
connection: {
type: 'timescaledb',
host: 'localhost',
port: 5432,
database: 'schobase',
user: 'postgres',
password: process.env.DB_PASSWORD!,
},
})
// Write data
await client.temperatures.write({
sensorId: 'temp-01',
timestamp: new Date(),
temperature: 23.5,
location: 'warehouse',
})| Property | Type | Description |
|---|---|---|
| type | 'timescaledb' | Backend type identifier |
| host | string | Database host address |
| port | number | Database port (default: 5432) |
| database | string | Database name |
| user | string | Database username |
| password | string | Database password |
Fully managed time series database service by AWS. Best for cloud-native applications with serverless scaling.
import { createClient, defineSchema } from 'schobase'
import { z } from 'zod'
const schema = defineSchema({
tables: {
iotMetrics: {
validator: z.object({
deviceId: z.string(),
timestamp: z.date(),
temperature: z.number(),
humidity: z.number(),
pressure: z.number(),
}),
timeIndex: 'timestamp',
},
},
})
const client = await createClient({
backend: 'timestream',
schema,
connection: {
type: 'timestream',
region: 'us-east-1',
database: 'my-timestream-db',
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
},
})
// Write data
await client.iotMetrics.write({
deviceId: 'device-001',
timestamp: new Date(),
temperature: 25.3,
humidity: 65.2,
pressure: 1013.25,
})| Property | Type | Description |
|---|---|---|
| type | 'timestream' | Backend type identifier |
| region | string | AWS region (e.g., 'us-east-1') |
| database | string | Timestream database name |
| credentials? | object | AWS credentials (optional, uses IAM if omitted) |
Purpose-built time series database with high write performance. Best for IoT and real-time analytics workloads.
import { createClient, defineSchema } from 'schobase'
import { z } from 'zod'
const schema = defineSchema({
tables: {
sensorData: {
validator: z.object({
sensorId: z.string(),
timestamp: z.date(),
value: z.number(),
unit: z.string(),
}),
timeIndex: 'timestamp',
},
},
})
const client = await createClient({
backend: 'influxdb',
schema,
connection: {
type: 'influxdb',
url: 'http://localhost:8086',
token: process.env.INFLUXDB_TOKEN!,
org: 'my-org',
bucket: 'my-bucket',
},
})
// Write data
await client.sensorData.write({
sensorId: 'sensor-001',
timestamp: new Date(),
value: 42.7,
unit: 'celsius',
})| Property | Type | Description |
|---|---|---|
| type | 'influxdb' | Backend type identifier |
| url | string | InfluxDB server URL |
| token | string | Authentication token |
| org | string | Organization name |
| bucket | string | Data bucket name |
Define your time series database schema.
function defineSchema<T extends Record<string, TableDefinition>>(
definition: { tables: T }
): Schema<T>| Property | Type | Description |
|---|---|---|
| validator | ZodSchema | Zod schema for type validation |
| timeIndex | string | Field name for time indexing |
| indexes? | string[] | Additional fields to index |
| retentionDays? | number | Data retention period in days |
import { defineSchema } from 'schobase'
import { z } from 'zod'
const schema = defineSchema({
tables: {
metrics: {
validator: z.object({
metricName: z.string(),
timestamp: z.date(),
value: z.number(),
tags: z.record(z.string()),
}),
timeIndex: 'timestamp',
indexes: ['metricName'],
retentionDays: 90,
},
},
})Write a single data point to the time series.
async function write<T>(data: T): Promise<WriteResult>await client.sensorReadings.write({
sensorId: 'temp-01',
timestamp: new Date(),
temperature: 23.5,
})Write multiple data points in a single request.
async function writeBatch<T>(data: T[]): Promise<BatchWriteResult>| Name | Type | Description |
|---|---|---|
| data | T[] | Array of records to write (max 1000 per batch) |
const readings = Array.from({ length: 100 }, (_, i) => ({
sensorId: 'temp-01',
timestamp: new Date(Date.now() - i * 1000),
temperature: 20 + Math.random() * 10,
}))
const result = await client.sensorReadings.writeBatch(readings)
console.log(`Wrote ${result.recordsIngested} records`)Create a query builder for type-safe queries.
function query(): QueryBuilder<T>where(field, operator, value) - Filter records by field valuetimeRange({ start, end }) - Filter by time rangeorderBy(field, direction) - Sort resultslimit(n) - Limit number of resultsoffset(n) - Skip first n resultsgroupBy(interval) - Group by time intervalaggregate(functions) - Calculate aggregatesexecute() - Execute the query and return resultsconst results = await client.sensorReadings
.query()
.where('sensorId', '==', 'temp-01')
.timeRange({
start: new Date('2024-01-01'),
end: new Date('2024-01-02'),
})
.orderBy('timestamp', 'desc')
.limit(100)
.execute()Perform time-based aggregations (avg, min, max, sum, count).
function aggregate(
functions: Record<string, AggregateFunction>
): QueryBuilder<AggregateResult>| Function | Description |
|---|---|
| avg | Calculate average value |
| min | Find minimum value |
| max | Find maximum value |
| sum | Sum all values |
| count | Count number of records |
| stddev | Calculate standard deviation |
| percentile | Calculate percentile (p50, p95, p99) |
const stats = await client.sensorReadings
.query()
.where('sensorId', '==', 'temp-01')
.timeRange({
start: new Date(Date.now() - 24 * 60 * 60 * 1000),
end: new Date(),
})
.groupBy('1h') // 1-hour buckets
.aggregate({
avgTemp: { field: 'temperature', fn: 'avg' },
maxTemp: { field: 'temperature', fn: 'max' },
minTemp: { field: 'temperature', fn: 'min' },
count: { fn: 'count' },
})
.execute()Subscribe to real-time data updates.
function subscribe(): SubscriptionBuilder<T>const unsubscribe = client.sensorReadings
.subscribe()
.where('sensorId', '==', 'temp-01')
.onUpdate((data) => {
console.log('New reading:', data)
})
.onError((error) => {
console.error('Subscription error:', error)
})
// Stop subscription
unsubscribe()Connect to OPC UA servers for industrial automation data.
new OpcUaAdapter({
endpoint: 'opc.tcp://...',
securityMode: 'SignAndEncrypt',
credentials: { ... }
})Poll Modbus TCP/RTU devices for sensor readings.
new ModbusAdapter({
host: '192.168.1.100',
port: 502,
unitId: 1
})Subscribe to MQTT topics from IoT devices.
new MqttAdapter({
brokerUrl: 'mqtt://...',
username: '...',
password: '...'
})Collect data from DNP3 devices (SCADA/utilities).
new Dnp3Adapter({
host: '...',
port: 20000,
masterAddress: 1
})SchoBase throws typed errors for validation failures, network issues, and server errors.
import { ValidationError, NetworkError, AuthError } from 'schobase'
try {
await client.sensorReadings.write({
sensorId: 'temp-01',
timestamp: new Date(),
temperature: 200, // Exceeds max of 125
})
} catch (error) {
if (error instanceof ValidationError) {
console.error('Validation failed:', error.issues)
} else if (error instanceof NetworkError) {
console.error('Network error:', error.message)
} else if (error instanceof AuthError) {
console.error('Authentication failed')
}
}All SchoBase APIs are fully typed. TypeScript will infer types based on your schema definition.
// Types are automatically inferred from schema
type SensorReading = z.infer<typeof schema.tables.sensorReadings.validator>
// Query results are typed
const results: SensorReading[] = await client.sensorReadings
.query()
.execute()
// Aggregation results have computed types
const stats: Array<{
bucket: Date
avgTemp: number
maxTemp: number
count: number
}> = await client.sensorReadings
.query()
.groupBy('1h')
.aggregate({ avgTemp: { ... }, maxTemp: { ... }, count: { ... } })
.execute()Check out our examples, tutorials, or join the community for support.