@housekit/orm 0.1.28 → 0.1.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,7 +14,7 @@ HouseKit ORM is a modern database toolkit designed specifically for ClickHouse.
14
14
  ## 🚀 Key Features
15
15
 
16
16
  - **🛡️ First-Class TypeScript**: Full type inference for every query. Schema definition acts as the single source of truth.
17
- - **🏎️ Binary Inserts by Default**: Native `RowBinary` serialization is used automatically. **5-10x faster** than JSON.
17
+ - **🏎️ High-Performance Inserts**: Optimized streaming with JSONCompact format and sync insert mode.
18
18
  - **🏗️ ClickHouse Native Engines**: Fluent DSL for `MergeTree`, `ReplacingMergeTree`, `SummingMergeTree`, `Distributed`, `Buffer`, and more.
19
19
  - **🔍 Advanced Analytics**: Specialized support for `ASOF JOIN`, `ARRAY JOIN`, `PREWHERE`, and complex Window Functions.
20
20
  - **🤝 Smart Relational API**: Query relations using `groupArray` internally, preventing row duplication.
@@ -74,7 +74,7 @@ import * as schema from './schema';
74
74
 
75
75
  const db = housekit({ url: 'http://localhost:8123' }, { schema });
76
76
 
77
- // Binary insert (default, fastest)
77
+ // Standard insert (no data returned)
78
78
  await db.insert(schema.users).values({ email: 'a@b.com', role: 'admin' });
79
79
 
80
80
  // JSON insert with returning data
@@ -164,18 +164,32 @@ orderBy: [desc(users.createdAt), asc(users.name)]
164
164
 
165
165
  ## 🚀 High-Performance Inserts
166
166
 
167
- ### Binary Insert (Default)
168
-
169
- Binary format is used by default for maximum performance:
167
+ ### Default Insert
170
168
 
171
169
  ```typescript
172
- // Binary insert (no data returned)
170
+ // Standard insert (no data returned)
173
171
  await db.insert(events).values([
174
172
  { type: 'click', userId: '...' },
175
173
  { type: 'view', userId: '...' },
176
174
  ]);
177
175
  ```
178
176
 
177
+ ### Sync Insert (Fastest for Small Batches)
178
+
179
+ Use `.syncInsert()` for maximum speed with batches under 5k rows:
180
+
181
+ ```typescript
182
+ await db.insert(events).values(data).syncInsert();
183
+ ```
184
+
185
+ ### JSONCompact Format
186
+
187
+ Use `.useCompactFormat()` for better performance with larger batches:
188
+
189
+ ```typescript
190
+ await db.insert(events).values(data).useCompactFormat();
191
+ ```
192
+
179
193
  ### JSON Insert with Returning
180
194
 
181
195
  Use `.returningOne()` for single inserts or `.returning()` for multiple:
@@ -300,6 +314,32 @@ const query = await db.select()
300
314
 
301
315
  ---
302
316
 
317
+ ## 📊 Benchmarks
318
+
319
+ Performance tested on local ClickHouse (Docker) with Bun runtime:
320
+
321
+ | Rows | Method | Time | Throughput |
322
+ |------|--------|------|------------|
323
+ | 1,000 | JSON | 78ms | 12,821 rows/sec |
324
+ | 1,000 | JSONCompact | 67ms | 14,925 rows/sec |
325
+ | 1,000 | Sync Insert | 12ms | 83,333 rows/sec |
326
+ | 5,000 | JSON | 108ms | 46,296 rows/sec |
327
+ | 5,000 | JSONCompact | 56ms | 89,286 rows/sec |
328
+ | 10,000 | JSON | 171ms | 58,480 rows/sec |
329
+ | 10,000 | JSONCompact | 158ms | 63,291 rows/sec |
330
+
331
+ Key findings:
332
+ - **Sync insert** is fastest for small batches (<5k rows) - up to 6x faster
333
+ - **JSONCompact** provides ~2x improvement for medium batches
334
+ - For high-throughput scenarios, use `.syncInsert()` with batching
335
+
336
+ Run the benchmark yourself:
337
+ ```bash
338
+ bun run benchmark # in app directory
339
+ ```
340
+
341
+ ---
342
+
303
343
  ## ⚡ Performance Optimizations
304
344
 
305
345
  HouseKit includes several optimizations for maximum throughput in production environments.
@@ -125,21 +125,10 @@ export declare class ClickHouseInsertBuilder<TTable extends TableRuntime<any, an
125
125
  turbo(): this;
126
126
  execute(): Promise<TReturn>;
127
127
  /**
128
- * Resolve the actual format to use based on settings and table capabilities.
129
- *
130
- * Binary is preferred when:
131
- * - No columns require server-side UUID generation
132
- * - All column types are supported by our binary encoder
133
- *
134
- * Falls back to JSON when:
135
- * - Columns use server-side defaults (e.g., generateUUIDv4())
136
- * - Unsupported types are detected
128
+ * Resolve the actual format to use based on settings.
129
+ * Default is JSON (most reliable and well-optimized by the official client).
137
130
  */
138
131
  private resolveFormat;
139
- /**
140
- * Check if table and data are compatible with binary format
141
- */
142
- private canUseBinaryFormat;
143
132
  /**
144
133
  * Execute insert using JSON format
145
134
  */
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- import type { ClickHouseClientConfigOptions } from '@clickhouse/client';
2
1
  import { type TableDefinition, type TableColumns } from './core';
3
- import { createClientFromConfigObject, type ClientConfigWithSchema, type HousekitClient as HousekitClientType } from './client';
2
+ import { createClientFromConfigObject, type ClientConfigWithSchema, type HousekitClient as HousekitClientType, type HousekitClientConfig } from './client';
4
3
  import { generateSelectSchema, generateInsertSchema } from './codegen/zod';
5
4
  export { ClickHouseColumn } from './column';
6
5
  export { type TableDefinition, type TableColumns, type TableOptions, type IndexDefinition, type ProjectionDefinition, type InsertModel, type TableModel, type TableInsertArray, type TableRuntime, type TableInsert, index, projection, deriveTable, renderSchema } from './table';
@@ -67,7 +66,7 @@ export interface HouseKitConfig {
67
66
  * Load housekit.config.js/ts and create a client by name.
68
67
  */
69
68
  export declare function createClientFromConfig(databaseName?: string): Promise<HousekitClient>;
70
- export declare function housekit<TSchema extends Record<string, TableDefinition<any>> = Record<string, TableDefinition<any>>>(config: ClickHouseClientConfigOptions, options?: {
69
+ export declare function housekit<TSchema extends Record<string, TableDefinition<any>> = Record<string, TableDefinition<any>>>(config: HousekitClientConfig, options?: {
71
70
  schema?: TSchema;
72
71
  }): HousekitClientType<TSchema>;
73
72
  export declare function createSchema<TCols extends TableColumns>(table: TableDefinition<TCols>): {
package/dist/index.js CHANGED
@@ -4822,20 +4822,7 @@ class ClickHouseInsertBuilder {
4822
4822
  if (this._format !== "auto") {
4823
4823
  return this._format;
4824
4824
  }
4825
- const canUseBinary = this.canUseBinaryFormat(plan);
4826
- return canUseBinary ? "binary" : plan.useCompact ? "compact" : "json";
4827
- }
4828
- canUseBinaryFormat(plan) {
4829
- for (const col of plan.columns) {
4830
- if (col.useServerUUID) {
4831
- return false;
4832
- }
4833
- const type = col.column.type.toLowerCase();
4834
- if (type.includes("map(") || type.includes("tuple(") || type.includes("nested(") || type.includes("lowcardinality(")) {
4835
- return false;
4836
- }
4837
- }
4838
- return true;
4825
+ return plan.useCompact ? "compact" : "json";
4839
4826
  }
4840
4827
  async executeJsonInsert(plan, tableName, format) {
4841
4828
  const mode = format === "compact" ? "compact" : "json";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@housekit/orm",
3
- "version": "0.1.28",
3
+ "version": "0.1.29",
4
4
  "description": "Type-safe ClickHouse ORM with modern DX and ClickHouse-specific optimizations. Features Turbo Mode (RowBinary), full engine support, and advanced query capabilities.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",