@ereo/db 0.1.6
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 +1282 -0
- package/dist/adapter.d.ts +151 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/dedup.d.ts +70 -0
- package/dist/dedup.d.ts.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +505 -0
- package/dist/plugin.d.ts +117 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/pool.d.ts +139 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/types.d.ts +168 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ereo/db - Database Adapter Interface
|
|
3
|
+
*
|
|
4
|
+
* Core abstraction for ORM-agnostic database operations.
|
|
5
|
+
* Adapters implement this interface to provide consistent access patterns.
|
|
6
|
+
*/
|
|
7
|
+
import type { AppContext } from '@ereo/core';
|
|
8
|
+
import type { QueryResult, MutationResult, DedupResult, DedupStats, TransactionOptions, AdapterConfig, HealthCheckResult } from './types';
|
|
9
|
+
/**
|
|
10
|
+
* Request-scoped database client with query deduplication.
|
|
11
|
+
* Created per-request and provides automatic caching of identical queries.
|
|
12
|
+
*/
|
|
13
|
+
export interface RequestScopedClient<TSchema> {
|
|
14
|
+
/**
|
|
15
|
+
* The underlying database client (e.g., Drizzle instance).
|
|
16
|
+
* Use this for building and executing queries.
|
|
17
|
+
*/
|
|
18
|
+
readonly client: TSchema;
|
|
19
|
+
/**
|
|
20
|
+
* Execute a raw SQL query with automatic deduplication.
|
|
21
|
+
* Identical queries within the same request are cached.
|
|
22
|
+
*/
|
|
23
|
+
query<T = unknown>(sql: string, params?: unknown[]): Promise<DedupResult<QueryResult<T>>>;
|
|
24
|
+
/**
|
|
25
|
+
* Get deduplication statistics for this request.
|
|
26
|
+
*/
|
|
27
|
+
getDedupStats(): DedupStats;
|
|
28
|
+
/**
|
|
29
|
+
* Clear the deduplication cache.
|
|
30
|
+
* Call this after mutations to ensure fresh data.
|
|
31
|
+
*/
|
|
32
|
+
clearDedup(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Mark that a mutation has occurred, clearing relevant cache entries.
|
|
35
|
+
* Optionally specify table names to clear only related queries.
|
|
36
|
+
*/
|
|
37
|
+
invalidate(tables?: string[]): void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Core database adapter interface.
|
|
41
|
+
* All ORM adapters (Drizzle, Prisma, Kysely) implement this interface.
|
|
42
|
+
*
|
|
43
|
+
* @template TSchema - The schema type (e.g., Drizzle's `typeof schema`)
|
|
44
|
+
*/
|
|
45
|
+
export interface DatabaseAdapter<TSchema = unknown> {
|
|
46
|
+
/**
|
|
47
|
+
* Human-readable adapter name (e.g., 'drizzle-postgres', 'prisma').
|
|
48
|
+
*/
|
|
49
|
+
readonly name: string;
|
|
50
|
+
/**
|
|
51
|
+
* Whether this adapter is compatible with edge runtimes.
|
|
52
|
+
* Edge-compatible adapters can run in Cloudflare Workers, Vercel Edge, etc.
|
|
53
|
+
*/
|
|
54
|
+
readonly edgeCompatible: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Get the underlying database client.
|
|
57
|
+
* For Drizzle, this returns the Drizzle instance.
|
|
58
|
+
* Use this for direct database operations outside of request context.
|
|
59
|
+
*/
|
|
60
|
+
getClient(): TSchema;
|
|
61
|
+
/**
|
|
62
|
+
* Get a request-scoped client with query deduplication.
|
|
63
|
+
* Call this in middleware/loaders to get per-request caching.
|
|
64
|
+
*
|
|
65
|
+
* @param context - The request context from EreoJS
|
|
66
|
+
*/
|
|
67
|
+
getRequestClient(context: AppContext): RequestScopedClient<TSchema>;
|
|
68
|
+
/**
|
|
69
|
+
* Execute a raw SQL query.
|
|
70
|
+
*
|
|
71
|
+
* @param sql - The SQL query string
|
|
72
|
+
* @param params - Query parameters for parameterized queries
|
|
73
|
+
*/
|
|
74
|
+
query<T = unknown>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
|
|
75
|
+
/**
|
|
76
|
+
* Execute a raw SQL statement that modifies data.
|
|
77
|
+
*
|
|
78
|
+
* @param sql - The SQL statement (INSERT, UPDATE, DELETE)
|
|
79
|
+
* @param params - Statement parameters
|
|
80
|
+
*/
|
|
81
|
+
execute(sql: string, params?: unknown[]): Promise<MutationResult>;
|
|
82
|
+
/**
|
|
83
|
+
* Run operations within a transaction.
|
|
84
|
+
* Automatically handles commit on success and rollback on error.
|
|
85
|
+
*
|
|
86
|
+
* @param fn - Function receiving the transaction client
|
|
87
|
+
* @param options - Transaction configuration
|
|
88
|
+
*/
|
|
89
|
+
transaction<T>(fn: (tx: TSchema) => Promise<T>, options?: TransactionOptions): Promise<T>;
|
|
90
|
+
/**
|
|
91
|
+
* Begin a manual transaction.
|
|
92
|
+
* Returns a transaction object that must be committed or rolled back.
|
|
93
|
+
*
|
|
94
|
+
* @param options - Transaction configuration
|
|
95
|
+
*/
|
|
96
|
+
beginTransaction(options?: TransactionOptions): Promise<Transaction<TSchema>>;
|
|
97
|
+
/**
|
|
98
|
+
* Check database connectivity and health.
|
|
99
|
+
*/
|
|
100
|
+
healthCheck(): Promise<HealthCheckResult>;
|
|
101
|
+
/**
|
|
102
|
+
* Disconnect from the database and cleanup resources.
|
|
103
|
+
* Call this on application shutdown.
|
|
104
|
+
*/
|
|
105
|
+
disconnect(): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Manual transaction handle for explicit control.
|
|
109
|
+
*/
|
|
110
|
+
export interface Transaction<TSchema> {
|
|
111
|
+
/**
|
|
112
|
+
* The transaction-scoped database client.
|
|
113
|
+
*/
|
|
114
|
+
readonly client: TSchema;
|
|
115
|
+
/**
|
|
116
|
+
* Commit the transaction.
|
|
117
|
+
*/
|
|
118
|
+
commit(): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Rollback the transaction.
|
|
121
|
+
*/
|
|
122
|
+
rollback(): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Whether the transaction is still active.
|
|
125
|
+
*/
|
|
126
|
+
readonly isActive: boolean;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Factory function type for creating database adapters.
|
|
130
|
+
*/
|
|
131
|
+
export type AdapterFactory<TConfig extends AdapterConfig, TSchema> = (config: TConfig) => DatabaseAdapter<TSchema>;
|
|
132
|
+
/**
|
|
133
|
+
* Register an adapter instance globally.
|
|
134
|
+
* Useful for accessing the adapter from anywhere in the application.
|
|
135
|
+
*/
|
|
136
|
+
export declare function registerAdapter<TSchema>(name: string, adapter: DatabaseAdapter<TSchema>): void;
|
|
137
|
+
/**
|
|
138
|
+
* Get a registered adapter by name.
|
|
139
|
+
*/
|
|
140
|
+
export declare function getAdapter<TSchema = unknown>(name: string): DatabaseAdapter<TSchema> | undefined;
|
|
141
|
+
/**
|
|
142
|
+
* Get the default registered adapter.
|
|
143
|
+
* Returns the first registered adapter or undefined if none.
|
|
144
|
+
*/
|
|
145
|
+
export declare function getDefaultAdapter<TSchema = unknown>(): DatabaseAdapter<TSchema> | undefined;
|
|
146
|
+
/**
|
|
147
|
+
* Clear all registered adapters.
|
|
148
|
+
* Useful for testing.
|
|
149
|
+
*/
|
|
150
|
+
export declare function clearAdapterRegistry(): void;
|
|
151
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/dedup.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ereo/db - Query Deduplication
|
|
3
|
+
*
|
|
4
|
+
* Request-scoped query deduplication using EreoJS's RequestContext.
|
|
5
|
+
* Automatically caches identical queries within a single request to avoid
|
|
6
|
+
* redundant database calls (e.g., N+1 queries in nested loaders).
|
|
7
|
+
*/
|
|
8
|
+
import type { AppContext } from '@ereo/core';
|
|
9
|
+
import type { DedupStats, DedupResult } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Generate a cache key (fingerprint) for a query.
|
|
12
|
+
* The fingerprint is deterministic for the same query + params combination.
|
|
13
|
+
*
|
|
14
|
+
* @param query - SQL query or query identifier
|
|
15
|
+
* @param params - Query parameters
|
|
16
|
+
* @returns A string fingerprint suitable for use as a cache key
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateFingerprint(query: string, params?: unknown[]): string;
|
|
19
|
+
/**
|
|
20
|
+
* Execute a query with automatic deduplication.
|
|
21
|
+
* If an identical query was already executed in this request, returns the cached result.
|
|
22
|
+
*
|
|
23
|
+
* @param context - The request context
|
|
24
|
+
* @param query - SQL query or query identifier
|
|
25
|
+
* @param params - Query parameters
|
|
26
|
+
* @param executor - Function that executes the actual query
|
|
27
|
+
* @param options - Additional options for caching behavior
|
|
28
|
+
* @returns The query result wrapped with dedup metadata
|
|
29
|
+
*/
|
|
30
|
+
export declare function dedupQuery<T>(context: AppContext, query: string, params: unknown[] | undefined, executor: () => Promise<T>, options?: {
|
|
31
|
+
/** Tables affected by this query (for selective invalidation) */
|
|
32
|
+
tables?: string[];
|
|
33
|
+
/** Skip caching for this query */
|
|
34
|
+
noCache?: boolean;
|
|
35
|
+
}): Promise<DedupResult<T>>;
|
|
36
|
+
/**
|
|
37
|
+
* Clear the entire dedup cache for a request.
|
|
38
|
+
* Call this after mutations to ensure subsequent reads get fresh data.
|
|
39
|
+
*
|
|
40
|
+
* @param context - The request context
|
|
41
|
+
*/
|
|
42
|
+
export declare function clearDedupCache(context: AppContext): void;
|
|
43
|
+
/**
|
|
44
|
+
* Invalidate cache entries related to specific tables.
|
|
45
|
+
* More selective than clearing the entire cache.
|
|
46
|
+
*
|
|
47
|
+
* @param context - The request context
|
|
48
|
+
* @param tables - Table names to invalidate
|
|
49
|
+
*/
|
|
50
|
+
export declare function invalidateTables(context: AppContext, tables: string[]): void;
|
|
51
|
+
/**
|
|
52
|
+
* Get deduplication statistics for the current request.
|
|
53
|
+
*
|
|
54
|
+
* @param context - The request context
|
|
55
|
+
* @returns Statistics about query deduplication
|
|
56
|
+
*/
|
|
57
|
+
export declare function getRequestDedupStats(context: AppContext): DedupStats;
|
|
58
|
+
/**
|
|
59
|
+
* Get the current cache contents for debugging.
|
|
60
|
+
* Only use this in development.
|
|
61
|
+
*
|
|
62
|
+
* @param context - The request context
|
|
63
|
+
* @returns Array of cache entries with their keys
|
|
64
|
+
*/
|
|
65
|
+
export declare function debugGetCacheContents(context: AppContext): Array<{
|
|
66
|
+
key: string;
|
|
67
|
+
tables?: string[];
|
|
68
|
+
age: number;
|
|
69
|
+
}>;
|
|
70
|
+
//# sourceMappingURL=dedup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dedup.d.ts","sourceRoot":"","sources":["../src/dedup.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAqCvD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,CAwB7E;AA8CD;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAChC,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAC7B,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC1B,OAAO,CAAC,EAAE;IACR,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GACA,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CA4CzB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAKzD;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAc5E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,CAkBpE;AAMD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,UAAU,GAClB,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAUxD"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ereo/db - Database Adapter Abstractions
|
|
3
|
+
*
|
|
4
|
+
* This package provides ORM-agnostic database abstractions for EreoJS:
|
|
5
|
+
* - Adapter interface for pluggable database backends
|
|
6
|
+
* - Query deduplication for request-scoped caching
|
|
7
|
+
* - Connection pooling primitives
|
|
8
|
+
* - Type utilities for end-to-end type safety
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // Using with Drizzle adapter
|
|
12
|
+
* import { createDatabasePlugin, useDb } from '@ereo/db';
|
|
13
|
+
* import { createDrizzleAdapter } from '@ereo/db-drizzle';
|
|
14
|
+
*
|
|
15
|
+
* // In ereo.config.ts
|
|
16
|
+
* const adapter = createDrizzleAdapter({
|
|
17
|
+
* driver: 'postgres-js',
|
|
18
|
+
* url: process.env.DATABASE_URL,
|
|
19
|
+
* schema,
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* export default defineConfig({
|
|
23
|
+
* plugins: [createDatabasePlugin(adapter)],
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // In a route loader
|
|
27
|
+
* export const loader = createLoader({
|
|
28
|
+
* load: async ({ context }) => {
|
|
29
|
+
* const db = useDb(context);
|
|
30
|
+
* return db.client.select().from(users);
|
|
31
|
+
* },
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* @packageDocumentation
|
|
35
|
+
*/
|
|
36
|
+
export { type DatabaseAdapter, type RequestScopedClient, type Transaction, type AdapterFactory, registerAdapter, getAdapter, getDefaultAdapter, clearAdapterRegistry, } from './adapter';
|
|
37
|
+
export { generateFingerprint, dedupQuery, clearDedupCache, invalidateTables, getRequestDedupStats, debugGetCacheContents, } from './dedup';
|
|
38
|
+
export { ConnectionPool, DEFAULT_POOL_CONFIG, createEdgePoolConfig, createServerlessPoolConfig, withRetry, isCommonRetryableError, DEFAULT_RETRY_CONFIG, type PoolStats, type RetryConfig, } from './pool';
|
|
39
|
+
export { createDatabasePlugin, useDb, useAdapter, getDb, withTransaction, type DatabasePluginOptions, } from './plugin';
|
|
40
|
+
export { type QueryResult, type MutationResult, type DedupResult, type DedupStats, type PoolConfig, type AdapterConfig, type TransactionOptions, type IsolationLevel, type InferSelect, type InferInsert, type DatabaseTables, type TableNames, type TableType, type TypedWhere, type WhereOperator, type TypedOrderBy, type TypedSelect, type HealthCheckResult, DatabaseError, ConnectionError, QueryError, TransactionError, TimeoutError, } from './types';
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAMH,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,cAAc,EAEnB,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAMnB,OAAO,EAEL,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EAEpB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAMjB,OAAO,EAEL,cAAc,EAEd,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAE1B,SAAS,EACT,sBAAsB,EACtB,oBAAoB,EAEpB,KAAK,SAAS,EACd,KAAK,WAAW,GACjB,MAAM,QAAQ,CAAC;AAMhB,OAAO,EAEL,oBAAoB,EAEpB,KAAK,EACL,UAAU,EACV,KAAK,EAEL,eAAe,EAEf,KAAK,qBAAqB,GAC3B,MAAM,UAAU,CAAC;AAMlB,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,UAAU,EAEf,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EAEnB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,SAAS,EAEd,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EAEhB,KAAK,iBAAiB,EAEtB,aAAa,EACb,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,YAAY,GACb,MAAM,SAAS,CAAC"}
|