turbine-orm 0.7.1 → 0.9.0
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 +62 -40
- package/dist/cjs/cli/index.js +102 -10
- package/dist/cjs/cli/migrate.js +50 -13
- package/dist/cjs/cli/studio-ui.generated.js +6 -0
- package/dist/cjs/cli/studio.js +641 -0
- package/dist/cjs/client.js +43 -5
- package/dist/cjs/errors.js +43 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/pipeline-submittable.js +403 -0
- package/dist/cjs/pipeline.js +90 -37
- package/dist/cjs/query.js +865 -141
- package/dist/cjs/schema-builder.js +23 -3
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +103 -11
- package/dist/cli/migrate.d.ts +16 -0
- package/dist/cli/migrate.js +49 -13
- package/dist/cli/studio-ui.generated.d.ts +2 -0
- package/dist/cli/studio-ui.generated.js +4 -0
- package/dist/cli/studio.d.ts +75 -0
- package/dist/cli/studio.js +627 -0
- package/dist/client.d.ts +32 -3
- package/dist/client.js +44 -6
- package/dist/errors.d.ts +44 -0
- package/dist/errors.js +41 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/pipeline-submittable.d.ts +94 -0
- package/dist/pipeline-submittable.js +397 -0
- package/dist/pipeline.d.ts +37 -9
- package/dist/pipeline.js +89 -37
- package/dist/query.d.ts +142 -6
- package/dist/query.js +863 -141
- package/dist/schema-builder.js +23 -3
- package/package.json +8 -4
package/dist/query.d.ts
CHANGED
|
@@ -207,7 +207,17 @@ export interface FindManyArgs<T, R extends object = {}, W extends TypedWithClaus
|
|
|
207
207
|
timeout?: number;
|
|
208
208
|
}
|
|
209
209
|
export interface FindManyStreamArgs<T, R extends object = {}, W extends TypedWithClause<R> = TypedWithClause<R>> extends FindManyArgs<T, R, W> {
|
|
210
|
-
/**
|
|
210
|
+
/**
|
|
211
|
+
* Number of rows to fetch per internal FETCH batch (default: 1000).
|
|
212
|
+
*
|
|
213
|
+
* Trade-off: larger batches reduce network round-trips (important for
|
|
214
|
+
* high-latency connections like Neon) but increase per-batch memory.
|
|
215
|
+
* At 1000 rows x ~500 bytes/row the default is ~500 KB per batch.
|
|
216
|
+
*
|
|
217
|
+
* When the total result set fits within one batch, the stream avoids
|
|
218
|
+
* cursor overhead entirely (no BEGIN / DECLARE / CLOSE / COMMIT) by
|
|
219
|
+
* using a speculative `SELECT ... LIMIT batchSize+1` first.
|
|
220
|
+
*/
|
|
211
221
|
batchSize?: number;
|
|
212
222
|
}
|
|
213
223
|
export interface CreateArgs<T> {
|
|
@@ -370,6 +380,25 @@ export interface ArrayFilter {
|
|
|
370
380
|
/** Check if array is empty: array_length(column, 1) IS NULL */
|
|
371
381
|
isEmpty?: boolean;
|
|
372
382
|
}
|
|
383
|
+
/** Cached SQL template paired with its prepared-statement name. */
|
|
384
|
+
export interface SqlCacheEntry {
|
|
385
|
+
sql: string;
|
|
386
|
+
name: string;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* FNV-1a 64-bit hash returning 16 lowercase hex chars.
|
|
390
|
+
* Single-loop string iteration. Uses BigInt for 64-bit math.
|
|
391
|
+
*
|
|
392
|
+
* @internal Exported for testing only.
|
|
393
|
+
*/
|
|
394
|
+
export declare function fnv1a64Hex(s: string): string;
|
|
395
|
+
/**
|
|
396
|
+
* Derive a prepared-statement name from a SQL string.
|
|
397
|
+
* Format: `t_<16hex>` — always 18 chars, well under NAMEDATALEN (63).
|
|
398
|
+
*
|
|
399
|
+
* @internal Exported for testing only.
|
|
400
|
+
*/
|
|
401
|
+
export declare function sqlToPreparedName(sql: string): string;
|
|
373
402
|
export interface DeferredQuery<T> {
|
|
374
403
|
/** SQL text with $1, $2 placeholders */
|
|
375
404
|
sql: string;
|
|
@@ -379,6 +408,8 @@ export interface DeferredQuery<T> {
|
|
|
379
408
|
transform: (result: pg.QueryResult) => T;
|
|
380
409
|
/** Tag for debugging / logging */
|
|
381
410
|
tag: string;
|
|
411
|
+
/** Prepared statement name (t_<16hex>). Set when SQL cache is enabled. */
|
|
412
|
+
preparedName?: string;
|
|
382
413
|
}
|
|
383
414
|
/** Middleware function type — imported from client to avoid circular deps */
|
|
384
415
|
type MiddlewareFn = (params: {
|
|
@@ -402,17 +433,36 @@ export interface QueryInterfaceOptions {
|
|
|
402
433
|
* full tables).
|
|
403
434
|
*/
|
|
404
435
|
warnOnUnlimited?: boolean;
|
|
436
|
+
/**
|
|
437
|
+
* Enable prepared statements. When true, queries are submitted with a
|
|
438
|
+
* `{ name, text, values }` object to the pg driver, which caches the
|
|
439
|
+
* parse+plan on the server per connection.
|
|
440
|
+
*
|
|
441
|
+
* Default: `true` for Turbine-owned pools, `false` for external pools
|
|
442
|
+
* (serverless drivers may not support named statements).
|
|
443
|
+
*/
|
|
444
|
+
preparedStatements?: boolean;
|
|
445
|
+
/**
|
|
446
|
+
* Enable the SQL template cache. When true, repeated queries with the
|
|
447
|
+
* same shape (same keys, operators, relations — different values) reuse
|
|
448
|
+
* cached SQL text instead of rebuilding from scratch.
|
|
449
|
+
*
|
|
450
|
+
* Default: `true`. Set to `false` as a nuclear kill switch.
|
|
451
|
+
*/
|
|
452
|
+
sqlCache?: boolean;
|
|
405
453
|
}
|
|
406
454
|
export declare class QueryInterface<T extends object, R extends object = {}> {
|
|
407
455
|
private readonly pool;
|
|
408
456
|
private readonly table;
|
|
409
457
|
private readonly schema;
|
|
410
458
|
private readonly tableMeta;
|
|
411
|
-
/** SQL template cache: cacheKey →
|
|
412
|
-
private readonly
|
|
459
|
+
/** SQL template cache: cacheKey → SqlCacheEntry (sql + prepared statement name) */
|
|
460
|
+
private readonly sqlTemplateCache;
|
|
413
461
|
private readonly middlewares;
|
|
414
462
|
private readonly defaultLimit?;
|
|
415
463
|
private readonly warnOnUnlimited;
|
|
464
|
+
private readonly preparedStatementsEnabled;
|
|
465
|
+
private readonly sqlCacheEnabled;
|
|
416
466
|
/**
|
|
417
467
|
* Tracks tables that have already triggered an unlimited-query warning so
|
|
418
468
|
* the user is not spammed once per row. Per-instance state — each
|
|
@@ -422,10 +472,31 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
|
|
|
422
472
|
* cross-table sharing.
|
|
423
473
|
*/
|
|
424
474
|
private readonly warnedTables;
|
|
475
|
+
/** Cache hit/miss counters for diagnostics */
|
|
476
|
+
private cacheHits;
|
|
477
|
+
private cacheMisses;
|
|
425
478
|
/** Pre-computed column type lookups (avoids linear scans per query) */
|
|
426
479
|
private readonly columnPgTypeMap;
|
|
427
480
|
private readonly columnArrayTypeMap;
|
|
428
481
|
constructor(pool: pg.Pool, table: string, schema: SchemaMetadata, middlewares?: MiddlewareFn[], options?: QueryInterfaceOptions);
|
|
482
|
+
/**
|
|
483
|
+
* Return cache hit/miss statistics for this QueryInterface instance.
|
|
484
|
+
* Useful for monitoring and benchmarking.
|
|
485
|
+
*/
|
|
486
|
+
cacheStats(): {
|
|
487
|
+
hits: number;
|
|
488
|
+
misses: number;
|
|
489
|
+
hitRate: number;
|
|
490
|
+
size: number;
|
|
491
|
+
};
|
|
492
|
+
/**
|
|
493
|
+
* Look up or build a SQL template in the cache.
|
|
494
|
+
* On miss, calls `build()` to generate the SQL, stores the entry, and returns it.
|
|
495
|
+
* On hit, increments counters and returns the cached entry.
|
|
496
|
+
*
|
|
497
|
+
* When `sqlCache` is disabled, always calls `build()` without caching.
|
|
498
|
+
*/
|
|
499
|
+
private acquireSql;
|
|
429
500
|
/**
|
|
430
501
|
* Reset the per-instance unlimited-query warning dedupe set.
|
|
431
502
|
* Exposed for tests so a single test process can verify the warning fires
|
|
@@ -467,9 +538,21 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
|
|
|
467
538
|
* Stream rows from a findMany query using PostgreSQL cursors.
|
|
468
539
|
* Returns an AsyncIterable that yields individual rows, fetching in batches internally.
|
|
469
540
|
*
|
|
470
|
-
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
541
|
+
* **Speculative fast-path:** Before opening a cursor, issues a single
|
|
542
|
+
* `SELECT ... LIMIT batchSize+1`. If the result fits within `batchSize`,
|
|
543
|
+
* all rows are yielded immediately with zero cursor overhead (no BEGIN /
|
|
544
|
+
* DECLARE / CLOSE / COMMIT). Only when the result overflows does the
|
|
545
|
+
* method fall back to the full cursor path.
|
|
546
|
+
*
|
|
547
|
+
* **Cursor path:** Uses DECLARE CURSOR within a dedicated transaction on a
|
|
548
|
+
* single pooled connection. The cursor is automatically closed and the
|
|
549
|
+
* connection released when iteration completes or is terminated early
|
|
550
|
+
* (e.g. `break` from `for await`).
|
|
551
|
+
*
|
|
552
|
+
* **Snapshot semantics note:** The speculative fast-path runs outside a
|
|
553
|
+
* transaction. If the result overflows and the cursor path is opened, the
|
|
554
|
+
* cursor runs in its own transaction — spanning two separate snapshots.
|
|
555
|
+
* For strict single-snapshot semantics, wrap the call in `$transaction`.
|
|
473
556
|
*
|
|
474
557
|
* @example
|
|
475
558
|
* ```ts
|
|
@@ -538,6 +621,59 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
|
|
|
538
621
|
* clause numbering continues correctly afterward.
|
|
539
622
|
*/
|
|
540
623
|
private buildSetClause;
|
|
624
|
+
/**
|
|
625
|
+
* Produce a value-invariant fingerprint of a where clause.
|
|
626
|
+
* Same keys + same operator shapes + same combinator structure => same string.
|
|
627
|
+
* Different values (e.g. id=1 vs id=999) => identical fingerprint.
|
|
628
|
+
*
|
|
629
|
+
* @internal Exposed as package-private for testing via class access.
|
|
630
|
+
*/
|
|
631
|
+
fingerprintWhere(where: Record<string, unknown>): string;
|
|
632
|
+
/**
|
|
633
|
+
* Fingerprint a relation filter sub-where for some/every/none.
|
|
634
|
+
*/
|
|
635
|
+
private fingerprintRelFilter;
|
|
636
|
+
/**
|
|
637
|
+
* Walk a where clause and push ONLY values into `params`, in the EXACT same
|
|
638
|
+
* order that `buildWhereClause` pushes them. Used on cache hit to fill params
|
|
639
|
+
* without rebuilding SQL.
|
|
640
|
+
*
|
|
641
|
+
* @internal Exposed as package-private for testing.
|
|
642
|
+
*/
|
|
643
|
+
collectWhereParams(where: Record<string, unknown>, params: unknown[]): void;
|
|
644
|
+
/** Collect params from a relation filter sub-where. Mirrors buildSubWhereForRelation. */
|
|
645
|
+
private collectRelFilterParams;
|
|
646
|
+
/** Collect params from operator clauses. Mirrors buildOperatorClauses. */
|
|
647
|
+
private collectOperatorParams;
|
|
648
|
+
/** Collect params from JSON filter. Mirrors buildJsonFilterClauses. */
|
|
649
|
+
private collectJsonFilterParams;
|
|
650
|
+
/** Collect params from array filter. Mirrors buildArrayFilterClauses. */
|
|
651
|
+
private collectArrayFilterParams;
|
|
652
|
+
/**
|
|
653
|
+
* Produce a fingerprint for a `with` clause tree. Recursion mirrors
|
|
654
|
+
* buildSelectWithRelations / buildRelationSubquery.
|
|
655
|
+
*
|
|
656
|
+
* @internal Exposed as package-private for testing.
|
|
657
|
+
*/
|
|
658
|
+
withFingerprint(withClause: WithClause | undefined, table?: string, depth?: number): string;
|
|
659
|
+
/**
|
|
660
|
+
* Collect params from a `with` clause tree. Mirrors buildSelectWithRelations +
|
|
661
|
+
* buildRelationSubquery param-push order.
|
|
662
|
+
*/
|
|
663
|
+
private collectWithParams;
|
|
664
|
+
/**
|
|
665
|
+
* Collect params from a single relation subquery. Mirrors buildRelationSubquery.
|
|
666
|
+
*/
|
|
667
|
+
private collectRelationSubqueryParams;
|
|
668
|
+
/**
|
|
669
|
+
* Fingerprint SET clauses for update/updateMany.
|
|
670
|
+
* Captures key names + operator types (set/increment/etc) but not values.
|
|
671
|
+
*/
|
|
672
|
+
private fingerprintSet;
|
|
673
|
+
/**
|
|
674
|
+
* Collect SET params for update/updateMany. Mirrors buildSetClause param order.
|
|
675
|
+
*/
|
|
676
|
+
private collectSetParams;
|
|
541
677
|
/** Build WHERE clause from a where object (supports operators, NULL, OR) */
|
|
542
678
|
private buildWhere;
|
|
543
679
|
/**
|