@gravito/ripple 4.0.0 → 4.0.1
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/dist/atlas/src/DB.d.ts +51 -4
- package/dist/atlas/src/config/index.d.ts +1 -1
- package/dist/atlas/src/config/loadConfig.d.ts +0 -7
- package/dist/atlas/src/connection/Connection.d.ts +4 -0
- package/dist/atlas/src/connection/ConnectionManager.d.ts +75 -6
- package/dist/atlas/src/connection/ReplicaConnectionPool.d.ts +54 -0
- package/dist/atlas/src/drivers/MySQLDriver.d.ts +16 -3
- package/dist/atlas/src/drivers/PostgresDriver.d.ts +15 -2
- package/dist/atlas/src/index.d.ts +15 -3
- package/dist/atlas/src/observability/AtlasMetrics.d.ts +22 -0
- package/dist/atlas/src/orm/Repository.d.ts +247 -0
- package/dist/atlas/src/orm/index.d.ts +1 -0
- package/dist/atlas/src/orm/model/Model.d.ts +11 -2
- package/dist/atlas/src/orm/model/concerns/HasAttributes.d.ts +14 -0
- package/dist/atlas/src/orm/model/concerns/HasPersistence.d.ts +5 -0
- package/dist/atlas/src/orm/model/decorators.d.ts +29 -0
- package/dist/atlas/src/orm/model/index.d.ts +1 -1
- package/dist/atlas/src/orm/schema/SchemaRegistry.d.ts +1 -0
- package/dist/atlas/src/pool/AdaptivePoolManager.d.ts +98 -0
- package/dist/atlas/src/pool/PoolHealthChecker.d.ts +91 -0
- package/dist/atlas/src/pool/PoolStrategy.d.ts +129 -0
- package/dist/atlas/src/pool/PoolWarmer.d.ts +92 -0
- package/dist/atlas/src/query/QueryBuilder.d.ts +71 -1
- package/dist/atlas/src/query/RelationshipResolver.d.ts +23 -0
- package/dist/atlas/src/schema/MigrationGenerator.d.ts +45 -0
- package/dist/atlas/src/schema/SchemaDiff.d.ts +73 -0
- package/dist/atlas/src/schema/TypeGenerator.d.ts +57 -0
- package/dist/atlas/src/schema/TypeWriter.d.ts +42 -0
- package/dist/atlas/src/sharding/ShardingManager.d.ts +59 -0
- package/dist/atlas/src/types/index.d.ts +83 -1
- package/dist/atlas/src/utils/CursorEncoding.d.ts +63 -0
- package/dist/core/src/ConfigManager.d.ts +39 -0
- package/dist/core/src/Container/RequestScopeManager.d.ts +62 -0
- package/dist/core/src/Container/RequestScopeMetrics.d.ts +144 -0
- package/dist/core/src/Container.d.ts +45 -0
- package/dist/core/src/ErrorHandler.d.ts +3 -0
- package/dist/core/src/HookManager.d.ts +95 -0
- package/dist/core/src/PlanetCore.d.ts +89 -0
- package/dist/core/src/RequestContext.d.ts +97 -0
- package/dist/core/src/ServiceProvider.d.ts +22 -0
- package/dist/core/src/adapters/PhotonAdapter.d.ts +4 -0
- package/dist/core/src/adapters/bun/BunContext.d.ts +4 -0
- package/dist/core/src/cli/queue-commands.d.ts +6 -0
- package/dist/core/src/engine/AOTRouter.d.ts +6 -1
- package/dist/core/src/engine/FastContext.d.ts +23 -0
- package/dist/core/src/engine/Gravito.d.ts +0 -1
- package/dist/core/src/engine/MinimalContext.d.ts +21 -0
- package/dist/core/src/engine/types.d.ts +3 -0
- package/dist/core/src/error-handling/RequestScopeErrorContext.d.ts +126 -0
- package/dist/core/src/events/BackpressureManager.d.ts +215 -0
- package/dist/core/src/events/DeadLetterQueue.d.ts +75 -1
- package/dist/core/src/events/EventBackend.d.ts +2 -1
- package/dist/core/src/events/EventOptions.d.ts +99 -4
- package/dist/core/src/events/EventPriorityQueue.d.ts +105 -6
- package/dist/core/src/events/FlowControlStrategy.d.ts +109 -0
- package/dist/core/src/events/MessageQueueBridge.d.ts +184 -0
- package/dist/core/src/events/PriorityEscalationManager.d.ts +82 -0
- package/dist/core/src/events/RetryScheduler.d.ts +104 -0
- package/dist/core/src/events/WorkerPool.d.ts +98 -0
- package/dist/core/src/events/WorkerPoolConfig.d.ts +153 -0
- package/dist/core/src/events/WorkerPoolMetrics.d.ts +65 -0
- package/dist/core/src/events/aggregation/AggregationWindow.d.ts +77 -0
- package/dist/core/src/events/aggregation/DeduplicationManager.d.ts +135 -0
- package/dist/core/src/events/aggregation/EventAggregationManager.d.ts +108 -0
- package/dist/core/src/events/aggregation/EventBatcher.d.ts +99 -0
- package/dist/core/src/events/aggregation/types.d.ts +117 -0
- package/dist/core/src/events/index.d.ts +11 -0
- package/dist/core/src/events/observability/OTelEventMetrics.d.ts +92 -0
- package/dist/core/src/events/observability/StreamWorkerMetrics.d.ts +76 -0
- package/dist/core/src/events/observability/index.d.ts +4 -0
- package/dist/core/src/events/types.d.ts +59 -0
- package/dist/core/src/health/HealthProvider.d.ts +67 -0
- package/dist/core/src/http/types.d.ts +19 -0
- package/dist/core/src/index.d.ts +13 -1
- package/dist/core/src/observability/Metrics.d.ts +244 -0
- package/dist/core/src/observability/QueueDashboard.d.ts +136 -0
- package/dist/core/src/reliability/DeadLetterQueueManager.d.ts +34 -0
- package/dist/index.js +403 -40
- package/dist/index.js.map +11 -9
- package/dist/photon/src/index.d.ts +5 -0
- package/dist/photon/src/middleware/ratelimit-redis.d.ts +50 -0
- package/dist/photon/src/middleware/ratelimit.d.ts +4 -0
- package/dist/ripple/src/RippleServer.d.ts +0 -1
- package/dist/ripple/src/engines/UWebSocketsEngine.d.ts +97 -0
- package/dist/ripple/src/engines/WsEngine.d.ts +69 -0
- package/dist/ripple/src/engines/index.d.ts +4 -0
- package/dist/ripple/src/serializers/ISerializer.d.ts +1 -1
- package/dist/ripple/src/serializers/JsonSerializer.d.ts +1 -1
- package/dist/ripple/src/serializers/ProtobufSerializer.d.ts +6 -3
- package/dist/ripple/src/types.d.ts +11 -0
- package/package.json +3 -2
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @gravito/atlas - Connection Pool Warmer
|
|
3
|
+
* @description Preheats connection pools during initialization
|
|
4
|
+
*/
|
|
5
|
+
import type { ConnectionManager } from '../connection/ConnectionManager';
|
|
6
|
+
export interface PoolWarmerConfig {
|
|
7
|
+
/**
|
|
8
|
+
* Target number of connections to warm for each pool
|
|
9
|
+
* @default 2
|
|
10
|
+
*/
|
|
11
|
+
targetConnections?: number;
|
|
12
|
+
/**
|
|
13
|
+
* Number of concurrent warmup queries
|
|
14
|
+
* @default 2
|
|
15
|
+
*/
|
|
16
|
+
concurrency?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Timeout (ms) for each warmup query
|
|
19
|
+
* @default 5000
|
|
20
|
+
*/
|
|
21
|
+
timeout?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Callback when warmup completes
|
|
24
|
+
*/
|
|
25
|
+
onComplete?: (result: WarmupResult) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Callback for individual connection warmup
|
|
28
|
+
*/
|
|
29
|
+
onConnectionWarmed?: (connection: string, duration: number) => void;
|
|
30
|
+
}
|
|
31
|
+
export interface ConnectionWarmupResult {
|
|
32
|
+
/**
|
|
33
|
+
* Whether warmup succeeded
|
|
34
|
+
*/
|
|
35
|
+
success: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Connection name
|
|
38
|
+
*/
|
|
39
|
+
connection: string;
|
|
40
|
+
/**
|
|
41
|
+
* Time spent warming up (ms)
|
|
42
|
+
*/
|
|
43
|
+
duration: number;
|
|
44
|
+
/**
|
|
45
|
+
* Error message (if failed)
|
|
46
|
+
*/
|
|
47
|
+
error?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface WarmupResult {
|
|
50
|
+
/**
|
|
51
|
+
* Total connections processed
|
|
52
|
+
*/
|
|
53
|
+
total: number;
|
|
54
|
+
/**
|
|
55
|
+
* Number of successful warmups
|
|
56
|
+
*/
|
|
57
|
+
successful: number;
|
|
58
|
+
/**
|
|
59
|
+
* Number of failed warmups
|
|
60
|
+
*/
|
|
61
|
+
failed: number;
|
|
62
|
+
/**
|
|
63
|
+
* Results for each connection
|
|
64
|
+
*/
|
|
65
|
+
results: Record<string, ConnectionWarmupResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Total duration (ms)
|
|
68
|
+
*/
|
|
69
|
+
duration: number;
|
|
70
|
+
}
|
|
71
|
+
export declare const DEFAULT_WARMER_CONFIG: PoolWarmerConfig;
|
|
72
|
+
/**
|
|
73
|
+
* Connection pool warmer
|
|
74
|
+
* Preheats pools by establishing connections
|
|
75
|
+
*/
|
|
76
|
+
export declare class PoolWarmer {
|
|
77
|
+
private connectionManager;
|
|
78
|
+
private config;
|
|
79
|
+
constructor(connectionManager: ConnectionManager, config: PoolWarmerConfig);
|
|
80
|
+
/**
|
|
81
|
+
* Warm all connection pools
|
|
82
|
+
*/
|
|
83
|
+
warmAll(): Promise<WarmupResult>;
|
|
84
|
+
/**
|
|
85
|
+
* Warm a specific connection pool
|
|
86
|
+
*/
|
|
87
|
+
warmConnection(name: string): Promise<ConnectionWarmupResult>;
|
|
88
|
+
/**
|
|
89
|
+
* Execute a warmup query with timeout
|
|
90
|
+
*/
|
|
91
|
+
private executeWarmupQuery;
|
|
92
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Model, ModelConstructor } from '../orm/model/Model';
|
|
2
|
-
import type { BooleanOperator, CompiledQuery, ConnectionContract, GrammarContract, JoinType, Operator, OrderDirection, PaginateResult, QueryBuilderContract } from '../types';
|
|
2
|
+
import type { BooleanOperator, CompiledQuery, ConnectionContract, CursorPaginateResult, GrammarContract, JoinType, Operator, OrderDirection, PaginateResult, QueryBuilderContract } from '../types';
|
|
3
3
|
import { GroupByClause, HavingClause, JoinManager, LimitClause, OrderByClause, SelectClause, WhereClause } from './clauses';
|
|
4
4
|
import { Expression } from './Expression';
|
|
5
|
+
import type { RelationshipResolver } from './RelationshipResolver';
|
|
5
6
|
export declare class QueryBuilderError extends Error {
|
|
6
7
|
constructor(message: string);
|
|
7
8
|
}
|
|
@@ -30,6 +31,11 @@ export declare class RecordNotFoundError extends Error {
|
|
|
30
31
|
export declare class QueryBuilder<T = Record<string, unknown>> implements QueryBuilderContract<T> {
|
|
31
32
|
protected readonly connection: ConnectionContract;
|
|
32
33
|
protected readonly grammar: GrammarContract;
|
|
34
|
+
/**
|
|
35
|
+
* Global relationship resolver to avoid circular dependencies and require() calls.
|
|
36
|
+
* Injected by the Model layer.
|
|
37
|
+
*/
|
|
38
|
+
static relationshipResolver?: RelationshipResolver;
|
|
33
39
|
/**
|
|
34
40
|
* Name of the target database table.
|
|
35
41
|
*/
|
|
@@ -49,6 +55,12 @@ export declare class QueryBuilder<T = Record<string, unknown>> implements QueryB
|
|
|
49
55
|
* Read-only flag to bypass hydration for performance.
|
|
50
56
|
*/
|
|
51
57
|
protected isReadOnly: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* When true, this query will always use the write (primary) connection,
|
|
60
|
+
* even if read replicas are configured. Use after a write to avoid
|
|
61
|
+
* replication lag issues.
|
|
62
|
+
*/
|
|
63
|
+
protected _forceWrite: boolean;
|
|
52
64
|
/**
|
|
53
65
|
* Map of relationships to load alongside query results.
|
|
54
66
|
*/
|
|
@@ -246,6 +258,29 @@ export declare class QueryBuilder<T = Record<string, unknown>> implements QueryB
|
|
|
246
258
|
* OR version of {@link whereJsonContains}.
|
|
247
259
|
*/
|
|
248
260
|
orWhereJsonContains(column: string, value: unknown): this;
|
|
261
|
+
/**
|
|
262
|
+
* Spatial distance filter: matches records within a given radius.
|
|
263
|
+
*
|
|
264
|
+
* Generates dialect-appropriate SQL:
|
|
265
|
+
* - **PostgreSQL**: `ST_DWithin(column::geography, ST_MakePoint(lng, lat)::geography, distance)`
|
|
266
|
+
* - **MySQL**: `ST_Distance_Sphere(column, POINT(lng, lat)) <= distance`
|
|
267
|
+
*
|
|
268
|
+
* Requires a spatial/geometry column and a GIS extension.
|
|
269
|
+
*
|
|
270
|
+
* @param column - The geometry/geography column name
|
|
271
|
+
* @param point - GPS point `{ lat, lng }` in decimal degrees
|
|
272
|
+
* @param distanceMeters - Search radius in meters
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```typescript
|
|
276
|
+
* // Find all stores within 5km of a location
|
|
277
|
+
* await Store.query().whereDistanceWithin('location', { lat: 25.04, lng: 121.52 }, 5000).get()
|
|
278
|
+
* ```
|
|
279
|
+
*/
|
|
280
|
+
whereDistanceWithin(column: string, point: {
|
|
281
|
+
lat: number;
|
|
282
|
+
lng: number;
|
|
283
|
+
}, distanceMeters: number): this;
|
|
249
284
|
/**
|
|
250
285
|
* Groups constraints in parentheses.
|
|
251
286
|
*
|
|
@@ -491,6 +526,41 @@ export declare class QueryBuilder<T = Record<string, unknown>> implements QueryB
|
|
|
491
526
|
* Alias for {@link paginate}.
|
|
492
527
|
*/
|
|
493
528
|
simplePaginate(perPage?: number, page?: number, primaryKey?: string): Promise<PaginateResult<T>>;
|
|
529
|
+
/**
|
|
530
|
+
* Forces this query to use the primary (write) connection.
|
|
531
|
+
*
|
|
532
|
+
* Essential after writes to avoid reading stale data from replicas.
|
|
533
|
+
* Example: after saving a model, use `.useWriteConnection()` to read back.
|
|
534
|
+
*
|
|
535
|
+
* @example
|
|
536
|
+
* ```typescript
|
|
537
|
+
* await User.create({ name: 'Alice' })
|
|
538
|
+
* const alice = await User.query().useWriteConnection().where('name', 'Alice').first()
|
|
539
|
+
* ```
|
|
540
|
+
*/
|
|
541
|
+
useWriteConnection(): this;
|
|
542
|
+
/**
|
|
543
|
+
* Cursor-based pagination for large datasets.
|
|
544
|
+
*
|
|
545
|
+
* Achieves O(1) performance by using tuple comparison SQL instead of OFFSET.
|
|
546
|
+
* Ideal for infinite scroll, API cursors, and feeds with millions of records.
|
|
547
|
+
*
|
|
548
|
+
* @param limit - Number of records to fetch per page
|
|
549
|
+
* @param cursor - Opaque cursor from a previous page's `nextCursor` (undefined for first page)
|
|
550
|
+
* @param sortColumn - Column to sort by (defaults to primary key 'id')
|
|
551
|
+
* @param direction - Sort direction (defaults to 'asc')
|
|
552
|
+
* @returns CursorPaginateResult with data and cursor metadata
|
|
553
|
+
*
|
|
554
|
+
* @example
|
|
555
|
+
* ```typescript
|
|
556
|
+
* // First page
|
|
557
|
+
* const page1 = await User.query().orderBy('created_at').cursorPaginate(20)
|
|
558
|
+
*
|
|
559
|
+
* // Next page using cursor from previous result
|
|
560
|
+
* const page2 = await User.query().orderBy('created_at').cursorPaginate(20, page1.nextCursor)
|
|
561
|
+
* ```
|
|
562
|
+
*/
|
|
563
|
+
cursorPaginate(limit?: number, cursor?: string, sortColumn?: string, direction?: 'asc' | 'desc'): Promise<CursorPaginateResult<T>>;
|
|
494
564
|
/**
|
|
495
565
|
* Processes the entire dataset in memory-efficient chunks.
|
|
496
566
|
*
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { QueryBuilderContract } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Relationship Metadata interface for QueryBuilder
|
|
4
|
+
*/
|
|
5
|
+
export interface RelationshipMeta {
|
|
6
|
+
type: string;
|
|
7
|
+
related: () => any;
|
|
8
|
+
foreignKey?: string;
|
|
9
|
+
localKey?: string;
|
|
10
|
+
pivotTable?: string;
|
|
11
|
+
relatedKey?: string;
|
|
12
|
+
pivotColumns?: string[];
|
|
13
|
+
morphName?: string;
|
|
14
|
+
morphTypeField?: string;
|
|
15
|
+
morphIdField?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Relationship Resolver interface to decouple QueryBuilder from Model relationships
|
|
19
|
+
*/
|
|
20
|
+
export interface RelationshipResolver {
|
|
21
|
+
getRelationships(model: any): Map<string, RelationshipMeta>;
|
|
22
|
+
eagerLoadMany(parents: any[], relations: string[] | Record<string, any> | Map<string, (query: QueryBuilderContract<any>) => void>): Promise<void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @gravito/atlas - Migration Generator
|
|
3
|
+
* @description Converts a SchemaDiffResult into SQL ALTER TABLE statements
|
|
4
|
+
* for both PostgreSQL and MySQL dialects.
|
|
5
|
+
*
|
|
6
|
+
* Powers the `migrate:generate` and `db:push` CLI commands.
|
|
7
|
+
*/
|
|
8
|
+
import type { DriverType } from '../types';
|
|
9
|
+
import type { SchemaDiffResult } from './SchemaDiff';
|
|
10
|
+
export interface MigrationGeneratorOptions {
|
|
11
|
+
/** Target database dialect */
|
|
12
|
+
dialect: DriverType;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* MigrationGenerator
|
|
16
|
+
*
|
|
17
|
+
* Takes a `SchemaDiffResult` and generates the corresponding SQL statements
|
|
18
|
+
* required to bring the database schema in sync with Model definitions.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const gen = new MigrationGenerator({ dialect: 'postgres' })
|
|
23
|
+
* const sql = gen.generate(diff)
|
|
24
|
+
* // Returns: ALTER TABLE users ADD COLUMN bio TEXT NULL; ...
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare class MigrationGenerator {
|
|
28
|
+
private readonly dialect;
|
|
29
|
+
constructor(options: MigrationGeneratorOptions);
|
|
30
|
+
/**
|
|
31
|
+
* Generate SQL statements for the given diff.
|
|
32
|
+
*
|
|
33
|
+
* @param diff - Schema diff result from SchemaDiff.compare()
|
|
34
|
+
* @returns Array of SQL statements to execute
|
|
35
|
+
*/
|
|
36
|
+
generate(diff: SchemaDiffResult): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Generate a timestamped migration script content string.
|
|
39
|
+
*
|
|
40
|
+
* @param diff - Schema diff result
|
|
41
|
+
* @param migrationName - Optional migration name
|
|
42
|
+
*/
|
|
43
|
+
generateMigrationScript(diff: SchemaDiffResult, migrationName?: string): string;
|
|
44
|
+
private quoteIdentifier;
|
|
45
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @gravito/atlas - Schema Differ
|
|
3
|
+
* @description Compares Atlas Model decorator metadata against the live database
|
|
4
|
+
* schema (information_schema) and produces a structured diff.
|
|
5
|
+
*
|
|
6
|
+
* This powers the `db:push` and `migrate:generate` CLI commands.
|
|
7
|
+
*/
|
|
8
|
+
import type { ConnectionContract } from '../types';
|
|
9
|
+
/**
|
|
10
|
+
* A single column definition from information_schema or decorator meta.
|
|
11
|
+
*/
|
|
12
|
+
export interface ColumnDefinition {
|
|
13
|
+
name: string;
|
|
14
|
+
type: string;
|
|
15
|
+
nullable: boolean;
|
|
16
|
+
defaultValue: string | null;
|
|
17
|
+
isPrimary: boolean;
|
|
18
|
+
isUnique: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The result of comparing two schema states.
|
|
22
|
+
*/
|
|
23
|
+
export interface SchemaDiffResult {
|
|
24
|
+
/** Table name */
|
|
25
|
+
table: string;
|
|
26
|
+
/** Columns that exist in models but not in the DB */
|
|
27
|
+
added: ColumnDefinition[];
|
|
28
|
+
/** Columns that exist in the DB but not in models */
|
|
29
|
+
removed: ColumnDefinition[];
|
|
30
|
+
/** Columns where the type or nullability has changed */
|
|
31
|
+
modified: Array<{
|
|
32
|
+
name: string;
|
|
33
|
+
from: ColumnDefinition;
|
|
34
|
+
to: ColumnDefinition;
|
|
35
|
+
}>;
|
|
36
|
+
/** Whether any changes were detected */
|
|
37
|
+
hasChanges: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface SchemaDiffOptions {
|
|
40
|
+
/** Database connection to compare against */
|
|
41
|
+
connection: ConnectionContract;
|
|
42
|
+
/** Table name */
|
|
43
|
+
table: string;
|
|
44
|
+
/** Desired column definitions (from Model decorators) */
|
|
45
|
+
desired: ColumnDefinition[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* SchemaDiff
|
|
49
|
+
*
|
|
50
|
+
* Compares the desired schema (from Model @Column decorators) against the
|
|
51
|
+
* current live database schema and produces a structured diff result.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* const differ = new SchemaDiff({ connection, table: 'users', desired: userColumns })
|
|
56
|
+
* const diff = await differ.compare()
|
|
57
|
+
* if (diff.hasChanges) console.log('Schema is out of sync!')
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare class SchemaDiff {
|
|
61
|
+
private readonly connection;
|
|
62
|
+
private readonly table;
|
|
63
|
+
private readonly desired;
|
|
64
|
+
constructor(options: SchemaDiffOptions);
|
|
65
|
+
/**
|
|
66
|
+
* Perform the schema comparison and return the diff result.
|
|
67
|
+
*/
|
|
68
|
+
compare(): Promise<SchemaDiffResult>;
|
|
69
|
+
/**
|
|
70
|
+
* Normalize DB type strings for comparison (e.g. 'character varying' → 'varchar').
|
|
71
|
+
*/
|
|
72
|
+
private normalizeType;
|
|
73
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @gravito/atlas - Schema Type Generator
|
|
3
|
+
* @description Reads @Column decorator metadata from Model classes and builds a
|
|
4
|
+
* type map for generating TypeScript declaration files.
|
|
5
|
+
*
|
|
6
|
+
* Eliminates "Type Drift" by deriving types 100% from decorator metadata.
|
|
7
|
+
*/
|
|
8
|
+
export declare const COLUMN_METADATA_KEY = "atlas:columns";
|
|
9
|
+
/**
|
|
10
|
+
* Column metadata stored by @Column decorator
|
|
11
|
+
*/
|
|
12
|
+
export interface ColumnMeta {
|
|
13
|
+
name: string;
|
|
14
|
+
type: string;
|
|
15
|
+
nullable?: boolean;
|
|
16
|
+
primary?: boolean;
|
|
17
|
+
unique?: boolean;
|
|
18
|
+
default?: unknown;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Generated type map for a single Model class
|
|
22
|
+
*/
|
|
23
|
+
export interface ModelTypeMap {
|
|
24
|
+
/** Model class name (e.g. 'User') */
|
|
25
|
+
modelName: string;
|
|
26
|
+
/** Table name the model maps to */
|
|
27
|
+
tableName: string;
|
|
28
|
+
/** Column-to-TypeScript type mapping */
|
|
29
|
+
columns: Record<string, string>;
|
|
30
|
+
}
|
|
31
|
+
export interface TypeGeneratorOptions {
|
|
32
|
+
/** Root directory to scan for Model files */
|
|
33
|
+
modelsDir: string;
|
|
34
|
+
/** Whether to log progress */
|
|
35
|
+
verbose?: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* TypeGenerator
|
|
39
|
+
*
|
|
40
|
+
* Scans a directory for Atlas Model files and extracts @Column decorator
|
|
41
|
+
* metadata to produce a complete type map.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* const gen = new TypeGenerator({ modelsDir: './src/models' })
|
|
46
|
+
* const result = await gen.generate()
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare class TypeGenerator {
|
|
50
|
+
private readonly modelsDir;
|
|
51
|
+
private readonly verbose;
|
|
52
|
+
constructor(options: TypeGeneratorOptions);
|
|
53
|
+
/**
|
|
54
|
+
* Scan models directory and extract type maps from all Model files.
|
|
55
|
+
*/
|
|
56
|
+
generate(): Promise<ModelTypeMap[]>;
|
|
57
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @gravito/atlas - Type Writer
|
|
3
|
+
* @description Writes TypeScript declaration files from generated Model type maps.
|
|
4
|
+
*
|
|
5
|
+
* Outputs interface declarations that can be merged into Model classes via
|
|
6
|
+
* Declaration Merging for zero type-drift DX.
|
|
7
|
+
*/
|
|
8
|
+
import type { ModelTypeMap } from './TypeGenerator';
|
|
9
|
+
export interface TypeWriterOptions {
|
|
10
|
+
/** Output file path (e.g., '.orbit/generated.d.ts') */
|
|
11
|
+
outputPath: string;
|
|
12
|
+
/** Optional banner comment */
|
|
13
|
+
banner?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* TypeWriter
|
|
17
|
+
*
|
|
18
|
+
* Converts a list of ModelTypeMap objects into a `.d.ts` declaration file.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const writer = new TypeWriter({ outputPath: '.orbit/generated.d.ts' })
|
|
23
|
+
* await writer.write(typeMaps)
|
|
24
|
+
* // Emits:
|
|
25
|
+
* // export interface GeneratedUser { id: number; name: string; ... }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare class TypeWriter {
|
|
29
|
+
private readonly outputPath;
|
|
30
|
+
private readonly banner;
|
|
31
|
+
constructor(options: TypeWriterOptions);
|
|
32
|
+
/**
|
|
33
|
+
* Write the declaration file to disk.
|
|
34
|
+
*
|
|
35
|
+
* @param typeMaps - Array of model type maps from TypeGenerator
|
|
36
|
+
*/
|
|
37
|
+
write(typeMaps: ModelTypeMap[]): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Build the .d.ts file content string.
|
|
40
|
+
*/
|
|
41
|
+
buildContent(typeMaps: ModelTypeMap[]): string;
|
|
42
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ConnectionConfig, ConnectionContract } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Sharding Configuration
|
|
4
|
+
*/
|
|
5
|
+
export interface ShardingConfig {
|
|
6
|
+
/**
|
|
7
|
+
* Number of shards
|
|
8
|
+
*/
|
|
9
|
+
shardCount: number;
|
|
10
|
+
/**
|
|
11
|
+
* List of shard connection configurations
|
|
12
|
+
*/
|
|
13
|
+
shards: (ConnectionConfig & {
|
|
14
|
+
id: number;
|
|
15
|
+
})[];
|
|
16
|
+
/**
|
|
17
|
+
* Sharding algorithm (default: 'consistent-hashing')
|
|
18
|
+
*/
|
|
19
|
+
algorithm?: 'consistent-hashing' | 'modulo' | 'range';
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Sharding Manager
|
|
23
|
+
*
|
|
24
|
+
* Manages database sharding, connection routing, and distributed queries.
|
|
25
|
+
* Supports horizontal scaling by partitioning data across multiple database instances.
|
|
26
|
+
*/
|
|
27
|
+
export declare class ShardingManager {
|
|
28
|
+
private connections;
|
|
29
|
+
private shardCount;
|
|
30
|
+
private algorithm;
|
|
31
|
+
constructor(config: ShardingConfig);
|
|
32
|
+
/**
|
|
33
|
+
* Initialize all shard connections
|
|
34
|
+
*/
|
|
35
|
+
private initializeShards;
|
|
36
|
+
/**
|
|
37
|
+
* Get a shard connection by distribution key (e.g., userId, tenantId)
|
|
38
|
+
*
|
|
39
|
+
* @param key - The distribution key
|
|
40
|
+
* @returns The connection instance for the calculated shard
|
|
41
|
+
*/
|
|
42
|
+
getShard(key: string | number): ConnectionContract;
|
|
43
|
+
/**
|
|
44
|
+
* Calculate Shard ID based on the key and selected algorithm
|
|
45
|
+
*/
|
|
46
|
+
private calculateShardId;
|
|
47
|
+
/**
|
|
48
|
+
* Execute a query across all shards and aggregate the results.
|
|
49
|
+
* Useful for reports, analytics, or global searches.
|
|
50
|
+
*
|
|
51
|
+
* @param callback - The operation to perform on each shard
|
|
52
|
+
* @returns Aggregated results from all shards
|
|
53
|
+
*/
|
|
54
|
+
mapReduce<T>(callback: (connection: ConnectionContract, shardId: number) => Promise<T[]>): Promise<T[]>;
|
|
55
|
+
/**
|
|
56
|
+
* Get all active shard connections
|
|
57
|
+
*/
|
|
58
|
+
getAllShards(): Map<number, ConnectionContract>;
|
|
59
|
+
}
|
|
@@ -74,6 +74,28 @@ export interface BaseConnectionConfig {
|
|
|
74
74
|
* Union type for all connection configurations
|
|
75
75
|
*/
|
|
76
76
|
export type ConnectionConfig = PostgresConfig | MySQLConfig | SQLiteConfig | MongoDBConfig | RedisConfig | BaseConnectionConfig;
|
|
77
|
+
/**
|
|
78
|
+
* Read/Write Replica configuration
|
|
79
|
+
* Defines a primary (write) node and one or more read replicas.
|
|
80
|
+
*/
|
|
81
|
+
export interface ReadWriteConnectionConfig {
|
|
82
|
+
/**
|
|
83
|
+
* Primary write node configuration
|
|
84
|
+
*/
|
|
85
|
+
write: ConnectionConfig;
|
|
86
|
+
/**
|
|
87
|
+
* Read replica configurations (Round-robin selected)
|
|
88
|
+
*/
|
|
89
|
+
read: ConnectionConfig[];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Union type for Atlas connection entry (standard or replica)
|
|
93
|
+
*/
|
|
94
|
+
export type AtlasConnectionEntry = ConnectionConfig | ReadWriteConnectionConfig;
|
|
95
|
+
/**
|
|
96
|
+
* Type guard to check if a connection config is a read/write replica config
|
|
97
|
+
*/
|
|
98
|
+
export declare function isReadWriteConfig(config: AtlasConnectionEntry): config is ReadWriteConnectionConfig;
|
|
77
99
|
export interface AtlasObservabilityConfig {
|
|
78
100
|
enabled: boolean;
|
|
79
101
|
tracing?: boolean;
|
|
@@ -82,7 +104,7 @@ export interface AtlasObservabilityConfig {
|
|
|
82
104
|
}
|
|
83
105
|
export interface AtlasConfig {
|
|
84
106
|
default: string;
|
|
85
|
-
connections: Record<string,
|
|
107
|
+
connections: Record<string, AtlasConnectionEntry>;
|
|
86
108
|
observability?: AtlasObservabilityConfig;
|
|
87
109
|
}
|
|
88
110
|
/**
|
|
@@ -459,6 +481,33 @@ export interface PaginateResult<T> {
|
|
|
459
481
|
hasPrev: boolean;
|
|
460
482
|
};
|
|
461
483
|
}
|
|
484
|
+
/**
|
|
485
|
+
* Cursor-based pagination result
|
|
486
|
+
* Provides O(1) performance regardless of dataset size.
|
|
487
|
+
* Ideal for infinite scroll and large datasets.
|
|
488
|
+
*/
|
|
489
|
+
export interface CursorPaginateResult<T> {
|
|
490
|
+
/**
|
|
491
|
+
* Current page data
|
|
492
|
+
*/
|
|
493
|
+
data: T[];
|
|
494
|
+
/**
|
|
495
|
+
* Opaque cursor pointing to the next page (null if no more data)
|
|
496
|
+
*/
|
|
497
|
+
nextCursor: string | null;
|
|
498
|
+
/**
|
|
499
|
+
* Opaque cursor pointing to the previous page (null if first page)
|
|
500
|
+
*/
|
|
501
|
+
prevCursor: string | null;
|
|
502
|
+
/**
|
|
503
|
+
* Whether more records exist beyond the current page
|
|
504
|
+
*/
|
|
505
|
+
hasMore: boolean;
|
|
506
|
+
/**
|
|
507
|
+
* Number of records returned
|
|
508
|
+
*/
|
|
509
|
+
count: number;
|
|
510
|
+
}
|
|
462
511
|
/**
|
|
463
512
|
* Connection pool statistics
|
|
464
513
|
*/
|
|
@@ -484,6 +533,27 @@ export interface PoolStats {
|
|
|
484
533
|
*/
|
|
485
534
|
max: number;
|
|
486
535
|
}
|
|
536
|
+
/**
|
|
537
|
+
* Connection pool health status
|
|
538
|
+
*/
|
|
539
|
+
export interface PoolHealth {
|
|
540
|
+
/**
|
|
541
|
+
* Health status: 'healthy' | 'warning' | 'critical' | 'disconnected'
|
|
542
|
+
*/
|
|
543
|
+
status: 'healthy' | 'warning' | 'critical' | 'disconnected';
|
|
544
|
+
/**
|
|
545
|
+
* Human-readable health message
|
|
546
|
+
*/
|
|
547
|
+
message: string;
|
|
548
|
+
/**
|
|
549
|
+
* Pool statistics (when available)
|
|
550
|
+
*/
|
|
551
|
+
stats?: PoolStats;
|
|
552
|
+
/**
|
|
553
|
+
* Last health check timestamp
|
|
554
|
+
*/
|
|
555
|
+
lastCheck?: Date;
|
|
556
|
+
}
|
|
487
557
|
/**
|
|
488
558
|
* Model base class (forward declaration)
|
|
489
559
|
* Actual implementation in src/orm/model/Model.ts
|
|
@@ -571,6 +641,18 @@ export interface DriverContract {
|
|
|
571
641
|
* @returns Pool statistics or null if not supported
|
|
572
642
|
*/
|
|
573
643
|
getPoolStats?(): PoolStats | null;
|
|
644
|
+
/**
|
|
645
|
+
* Get connection pool health status
|
|
646
|
+
* @optional Only implemented by drivers that support connection pooling
|
|
647
|
+
* @returns Pool health information
|
|
648
|
+
*/
|
|
649
|
+
getPoolHealth?(): PoolHealth;
|
|
650
|
+
/**
|
|
651
|
+
* Adjust the connection pool size dynamically
|
|
652
|
+
* @optional Only implemented by drivers that support pool resizing
|
|
653
|
+
* @param targetSize - Target number of connections
|
|
654
|
+
*/
|
|
655
|
+
adjustPoolSize?(targetSize: number): Promise<void>;
|
|
574
656
|
}
|
|
575
657
|
/**
|
|
576
658
|
* Connection Contract
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @gravito/atlas - Cursor Encoding Utility
|
|
3
|
+
* @description Base64 encode/decode for cursor-based pagination cursors.
|
|
4
|
+
*
|
|
5
|
+
* Cursor format: base64(JSON({ id, sortValue, sortColumn, direction }))
|
|
6
|
+
* This enables O(1) pagination using tuple comparison SQL:
|
|
7
|
+
* WHERE (sort_col, id) > (val, id_val)
|
|
8
|
+
*/
|
|
9
|
+
export interface CursorPayload {
|
|
10
|
+
/**
|
|
11
|
+
* Primary key value of the last/first record in the current page
|
|
12
|
+
*/
|
|
13
|
+
id: unknown;
|
|
14
|
+
/**
|
|
15
|
+
* Value of the sort column at the cursor boundary
|
|
16
|
+
*/
|
|
17
|
+
sortValue: unknown;
|
|
18
|
+
/**
|
|
19
|
+
* Column name used for sorting
|
|
20
|
+
*/
|
|
21
|
+
sortColumn: string;
|
|
22
|
+
/**
|
|
23
|
+
* Sort direction
|
|
24
|
+
*/
|
|
25
|
+
direction: 'asc' | 'desc';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Encode a cursor payload to an opaque base64 string.
|
|
29
|
+
*
|
|
30
|
+
* @param payload - Cursor data to encode
|
|
31
|
+
* @returns Base64-encoded cursor string
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* const cursor = encodeCursor({ id: 42, sortValue: '2026-01-01', sortColumn: 'created_at', direction: 'asc' })
|
|
35
|
+
*/
|
|
36
|
+
export declare function encodeCursor(payload: CursorPayload): string;
|
|
37
|
+
/**
|
|
38
|
+
* Decode a cursor string back to its payload.
|
|
39
|
+
*
|
|
40
|
+
* @param cursor - Base64 cursor string
|
|
41
|
+
* @returns Decoded cursor payload
|
|
42
|
+
* @throws {Error} If the cursor is malformed or tampered with
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* const payload = decodeCursor(cursor)
|
|
46
|
+
* // payload.id, payload.sortValue, etc.
|
|
47
|
+
*/
|
|
48
|
+
export declare function decodeCursor(cursor: string): CursorPayload;
|
|
49
|
+
/**
|
|
50
|
+
* Build the WHERE clause raw SQL and bindings for cursor pagination.
|
|
51
|
+
*
|
|
52
|
+
* For ascending sort: WHERE (sort_col, id) > (sort_val, id_val)
|
|
53
|
+
* For descending sort: WHERE (sort_col, id) < (sort_val, id_val)
|
|
54
|
+
*
|
|
55
|
+
* Uses tuple comparison which is O(1) on indexed columns in Postgres & MySQL.
|
|
56
|
+
*
|
|
57
|
+
* @param payload - Decoded cursor payload
|
|
58
|
+
* @returns { sql, bindings } ready for whereRaw()
|
|
59
|
+
*/
|
|
60
|
+
export declare function buildCursorWhereClause(payload: CursorPayload, idColumn?: string): {
|
|
61
|
+
sql: string;
|
|
62
|
+
bindings: unknown[];
|
|
63
|
+
};
|