@spfn/core 0.2.0-beta.5 → 0.2.0-beta.51
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/LICENSE +1 -1
- package/README.md +181 -1281
- package/dist/{boss-BO8ty33K.d.ts → boss-Cxqc-Oiw.d.ts} +37 -7
- package/dist/cache/index.js +32 -29
- package/dist/cache/index.js.map +1 -1
- package/dist/codegen/index.d.ts +55 -8
- package/dist/codegen/index.js +179 -5
- package/dist/codegen/index.js.map +1 -1
- package/dist/config/index.d.ts +168 -6
- package/dist/config/index.js +29 -5
- package/dist/config/index.js.map +1 -1
- package/dist/db/index.d.ts +218 -4
- package/dist/db/index.js +351 -57
- package/dist/db/index.js.map +1 -1
- package/dist/env/index.d.ts +26 -2
- package/dist/env/index.js +11 -2
- package/dist/env/index.js.map +1 -1
- package/dist/env/loader.d.ts +26 -19
- package/dist/env/loader.js +32 -25
- package/dist/env/loader.js.map +1 -1
- package/dist/errors/index.js.map +1 -1
- package/dist/event/index.d.ts +33 -3
- package/dist/event/index.js +17 -1
- package/dist/event/index.js.map +1 -1
- package/dist/event/sse/client.d.ts +42 -3
- package/dist/event/sse/client.js +128 -45
- package/dist/event/sse/client.js.map +1 -1
- package/dist/event/sse/index.d.ts +12 -5
- package/dist/event/sse/index.js +188 -20
- package/dist/event/sse/index.js.map +1 -1
- package/dist/event/ws/client.d.ts +59 -0
- package/dist/event/ws/client.js +273 -0
- package/dist/event/ws/client.js.map +1 -0
- package/dist/event/ws/index.d.ts +94 -0
- package/dist/event/ws/index.js +213 -0
- package/dist/event/ws/index.js.map +1 -0
- package/dist/job/index.d.ts +23 -8
- package/dist/job/index.js +154 -44
- package/dist/job/index.js.map +1 -1
- package/dist/logger/index.d.ts +5 -0
- package/dist/logger/index.js +14 -0
- package/dist/logger/index.js.map +1 -1
- package/dist/middleware/index.d.ts +23 -1
- package/dist/middleware/index.js +58 -5
- package/dist/middleware/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +2 -2
- package/dist/nextjs/index.js +77 -31
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +44 -23
- package/dist/nextjs/server.js +83 -65
- package/dist/nextjs/server.js.map +1 -1
- package/dist/route/index.d.ts +158 -4
- package/dist/route/index.js +238 -22
- package/dist/route/index.js.map +1 -1
- package/dist/server/index.d.ts +308 -17
- package/dist/server/index.js +1128 -261
- package/dist/server/index.js.map +1 -1
- package/dist/{router-Di7ENoah.d.ts → token-manager-CyG7la3p.d.ts} +116 -1
- package/dist/{types-D_N_U-Py.d.ts → types-7Mhoxnnt.d.ts} +21 -1
- package/dist/types-C1jMLGwK.d.ts +257 -0
- package/dist/types-Cfj--lfr.d.ts +151 -0
- package/docs/file-upload.md +717 -0
- package/package.json +18 -5
- package/dist/types-B-e_f2dQ.d.ts +0 -121
package/dist/db/index.d.ts
CHANGED
|
@@ -273,6 +273,36 @@ declare function initDatabase(options?: DatabaseOptions): Promise<{
|
|
|
273
273
|
* ```
|
|
274
274
|
*/
|
|
275
275
|
declare function closeDatabase(): Promise<void>;
|
|
276
|
+
/**
|
|
277
|
+
* Force an immediate database pool rebuild
|
|
278
|
+
*
|
|
279
|
+
* Destroys the current postgres.js pool(s) and rebuilds them with the same
|
|
280
|
+
* configuration passed to the original `initDatabase()` call (or whatever
|
|
281
|
+
* was detected from environment variables). Uses the same atomic-swap
|
|
282
|
+
* strategy as the periodic health check: new connections are created and
|
|
283
|
+
* tested BEFORE the old ones are torn down, so `getDatabase()` callers never
|
|
284
|
+
* observe a missing instance.
|
|
285
|
+
*
|
|
286
|
+
* Use this when application code detects that the pool is stuck and does not
|
|
287
|
+
* want to wait for the next periodic health check tick. Concurrent calls are
|
|
288
|
+
* coalesced — if a reconnect is already in progress, this resolves to `false`
|
|
289
|
+
* without starting a second one.
|
|
290
|
+
*
|
|
291
|
+
* @param reason - Short label describing why the rebuild was requested (for logs)
|
|
292
|
+
* @returns `true` if a reconnection ran, `false` if one was already in-flight.
|
|
293
|
+
* Resolves after the rebuild completes (success or max retries exhausted).
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```typescript
|
|
297
|
+
* import { forceReconnectDatabase } from '@spfn/core/db';
|
|
298
|
+
*
|
|
299
|
+
* app.post('/admin/db/reconnect', async (c) => {
|
|
300
|
+
* const ran = await forceReconnectDatabase('admin_request');
|
|
301
|
+
* return c.json({ reconnected: ran });
|
|
302
|
+
* });
|
|
303
|
+
* ```
|
|
304
|
+
*/
|
|
305
|
+
declare function forceReconnectDatabase(reason?: string): Promise<boolean>;
|
|
276
306
|
/**
|
|
277
307
|
* Get database connection info (for debugging)
|
|
278
308
|
*
|
|
@@ -308,6 +338,60 @@ declare function getDatabaseInfo(): {
|
|
|
308
338
|
isReplica: boolean;
|
|
309
339
|
};
|
|
310
340
|
|
|
341
|
+
/**
|
|
342
|
+
* Reconnect Trigger — Query-error driven pool rebuild
|
|
343
|
+
*
|
|
344
|
+
* Complements the periodic health check with a fast-path: when application
|
|
345
|
+
* queries start failing with connection-level errors, we do not wait up to
|
|
346
|
+
* DB_HEALTH_CHECK_INTERVAL (default 60s) to notice. A sliding-window counter
|
|
347
|
+
* trips a force-reconnect as soon as the failure rate crosses a threshold.
|
|
348
|
+
*
|
|
349
|
+
* Why this exists:
|
|
350
|
+
* - postgres.js transparently drops dead sockets and opens new ones on the
|
|
351
|
+
* next query. A single `SELECT 1` on the periodic interval can therefore
|
|
352
|
+
* false-pass while user-facing queries keep hitting the remaining dead
|
|
353
|
+
* sockets in the pool.
|
|
354
|
+
* - This module observes real query errors and, when it sees a burst of
|
|
355
|
+
* connection-level failures, calls triggerForceReconnect() which performs
|
|
356
|
+
* the same atomic-swap rebuild as the health check.
|
|
357
|
+
*
|
|
358
|
+
* Configuration (env vars, hardcoded defaults):
|
|
359
|
+
* - DB_RECONNECT_ERROR_THRESHOLD (default 3): errors needed in window
|
|
360
|
+
* - DB_RECONNECT_ERROR_WINDOW_MS (default 10000): sliding window size
|
|
361
|
+
*/
|
|
362
|
+
/**
|
|
363
|
+
* Determine whether an error looks like a pool/connection failure
|
|
364
|
+
*
|
|
365
|
+
* Returns true when any layer in the error chain exposes a connection-level
|
|
366
|
+
* code (postgres.js driver code, Node network errno, PG SQLSTATE class 08 etc.)
|
|
367
|
+
* or is an instance of our own ConnectionError wrapper.
|
|
368
|
+
*
|
|
369
|
+
* Returns false for query errors (syntax, constraint violations, etc.) — those
|
|
370
|
+
* should NOT trigger a pool rebuild.
|
|
371
|
+
*/
|
|
372
|
+
declare function isConnectionLevelError(error: unknown): boolean;
|
|
373
|
+
/**
|
|
374
|
+
* Reset the internal error counter
|
|
375
|
+
*
|
|
376
|
+
* Exposed for tests that need a clean slate between cases. Does not clear
|
|
377
|
+
* the WeakSet (which is GC-backed and self-cleans with error lifetimes).
|
|
378
|
+
*/
|
|
379
|
+
declare function resetConnectionErrorCounter(): void;
|
|
380
|
+
/**
|
|
381
|
+
* Report a database error to the reconnect trigger
|
|
382
|
+
*
|
|
383
|
+
* Call this from any site that catches a query error before rethrowing.
|
|
384
|
+
* It is a no-op for non-connection-level errors. When the threshold is
|
|
385
|
+
* crossed it calls triggerForceReconnect() in the background — callers
|
|
386
|
+
* should NOT await it.
|
|
387
|
+
*
|
|
388
|
+
* Safe to call from any context: catches its own errors so it cannot
|
|
389
|
+
* disrupt the calling catch block. Deduplicates across error-chain
|
|
390
|
+
* re-wrapping so one failure counts exactly once regardless of how many
|
|
391
|
+
* catch layers it passes through.
|
|
392
|
+
*/
|
|
393
|
+
declare function reportDatabaseError(error: unknown): void;
|
|
394
|
+
|
|
311
395
|
/**
|
|
312
396
|
* Create database connection with exponential backoff retry strategy
|
|
313
397
|
*
|
|
@@ -376,6 +460,12 @@ interface DrizzleConfigOptions {
|
|
|
376
460
|
packageFilter?: string;
|
|
377
461
|
/** Expand glob patterns to actual file paths (useful for Drizzle Studio) */
|
|
378
462
|
expandGlobs?: boolean;
|
|
463
|
+
/** PostgreSQL schema filter for push/introspect commands */
|
|
464
|
+
schemaFilter?: string[];
|
|
465
|
+
/** Auto-detect PostgreSQL schemas from entity files (requires expandGlobs: true) */
|
|
466
|
+
autoDetectSchemas?: boolean;
|
|
467
|
+
/** Migration prefix strategy (default: 'timestamp') */
|
|
468
|
+
migrationPrefix?: 'index' | 'timestamp' | 'unix' | 'none';
|
|
379
469
|
}
|
|
380
470
|
/**
|
|
381
471
|
* Detect database dialect from connection URL
|
|
@@ -407,6 +497,21 @@ declare function getDrizzleConfig(options?: DrizzleConfigOptions): {
|
|
|
407
497
|
dbCredentials: {
|
|
408
498
|
url: string;
|
|
409
499
|
};
|
|
500
|
+
migrations: {
|
|
501
|
+
prefix: "timestamp" | "none" | "index" | "unix";
|
|
502
|
+
};
|
|
503
|
+
schemaFilter?: undefined;
|
|
504
|
+
} | {
|
|
505
|
+
schema: string | string[];
|
|
506
|
+
out: string;
|
|
507
|
+
dialect: "postgresql" | "mysql" | "sqlite";
|
|
508
|
+
dbCredentials: {
|
|
509
|
+
url: string;
|
|
510
|
+
};
|
|
511
|
+
schemaFilter: string[] | undefined;
|
|
512
|
+
migrations: {
|
|
513
|
+
prefix: "timestamp" | "none" | "index" | "unix";
|
|
514
|
+
};
|
|
410
515
|
};
|
|
411
516
|
/**
|
|
412
517
|
* Generate drizzle.config.ts file content
|
|
@@ -462,7 +567,7 @@ declare function timestamps(): {
|
|
|
462
567
|
/**
|
|
463
568
|
* Foreign key reference to another table
|
|
464
569
|
*
|
|
465
|
-
* Creates a
|
|
570
|
+
* Creates a bigint column with cascade delete.
|
|
466
571
|
* Type-safe: ensures the reference points to a valid PostgreSQL column.
|
|
467
572
|
*
|
|
468
573
|
* @param name - Column name (e.g., 'author' creates 'author_id')
|
|
@@ -482,7 +587,7 @@ declare function timestamps(): {
|
|
|
482
587
|
*/
|
|
483
588
|
declare function foreignKey<T extends PgColumn>(name: string, reference: () => T, options?: {
|
|
484
589
|
onDelete?: 'cascade' | 'set null' | 'restrict' | 'no action';
|
|
485
|
-
}): drizzle_orm.NotNull<drizzle_orm_pg_core.
|
|
590
|
+
}): drizzle_orm.NotNull<drizzle_orm_pg_core.PgBigInt53BuilderInitial<`${string}_id`>>;
|
|
486
591
|
/**
|
|
487
592
|
* Optional foreign key reference (nullable)
|
|
488
593
|
*
|
|
@@ -502,7 +607,7 @@ declare function foreignKey<T extends PgColumn>(name: string, reference: () => T
|
|
|
502
607
|
*/
|
|
503
608
|
declare function optionalForeignKey<T extends PgColumn>(name: string, reference: () => T, options?: {
|
|
504
609
|
onDelete?: 'cascade' | 'set null' | 'restrict' | 'no action';
|
|
505
|
-
}): drizzle_orm_pg_core.
|
|
610
|
+
}): drizzle_orm_pg_core.PgBigInt53BuilderInitial<`${string}_id`>;
|
|
506
611
|
/**
|
|
507
612
|
* UUID primary key
|
|
508
613
|
*
|
|
@@ -833,6 +938,10 @@ declare function getSchemaInfo(packageName: string): {
|
|
|
833
938
|
* Uses Record<string, unknown> to accept any schema shape
|
|
834
939
|
*/
|
|
835
940
|
type TransactionDB = PostgresJsDatabase<Record<string, unknown>>;
|
|
941
|
+
/**
|
|
942
|
+
* afterCommit callback type
|
|
943
|
+
*/
|
|
944
|
+
type AfterCommitCallback = () => void | Promise<void>;
|
|
836
945
|
/**
|
|
837
946
|
* Transaction context stored in AsyncLocalStorage
|
|
838
947
|
*/
|
|
@@ -842,7 +951,15 @@ type TransactionContext = {
|
|
|
842
951
|
/** Unique transaction ID for logging and tracing */
|
|
843
952
|
txId: string;
|
|
844
953
|
level: number;
|
|
954
|
+
/** Callbacks to execute after root transaction commits */
|
|
955
|
+
afterCommitCallbacks: AfterCommitCallback[];
|
|
845
956
|
};
|
|
957
|
+
/**
|
|
958
|
+
* Get current transaction object and metadata from AsyncLocalStorage
|
|
959
|
+
*
|
|
960
|
+
* @returns TransactionContext if available, null otherwise
|
|
961
|
+
*/
|
|
962
|
+
declare function getTransactionContext(): TransactionContext | null;
|
|
846
963
|
/**
|
|
847
964
|
* Get current transaction from AsyncLocalStorage
|
|
848
965
|
*
|
|
@@ -862,6 +979,31 @@ declare function getTransaction(): TransactionDB | null;
|
|
|
862
979
|
*/
|
|
863
980
|
declare function runWithTransaction<T>(tx: TransactionDB, txId: string, // Add txId parameter
|
|
864
981
|
callback: () => Promise<T>): Promise<T>;
|
|
982
|
+
/**
|
|
983
|
+
* Register a callback to run after the current transaction commits
|
|
984
|
+
*
|
|
985
|
+
* - Inside a transaction: queued and executed after root transaction commits
|
|
986
|
+
* - Outside a transaction: executed immediately (already "committed")
|
|
987
|
+
* - Nested transactions: callbacks bubble up to root transaction
|
|
988
|
+
* - Callbacks run outside transaction context (new connection for DB access)
|
|
989
|
+
* - Errors are logged but never thrown (commit already succeeded)
|
|
990
|
+
*
|
|
991
|
+
* @example
|
|
992
|
+
* ```typescript
|
|
993
|
+
* import { onAfterCommit } from '@spfn/core/db/transaction';
|
|
994
|
+
*
|
|
995
|
+
* async function submit(spaceId: string, chatId: string)
|
|
996
|
+
* {
|
|
997
|
+
* const publication = await publicationRepo.create({...});
|
|
998
|
+
* await requestRepo.updateStatusAtomically(...);
|
|
999
|
+
*
|
|
1000
|
+
* onAfterCommit(() => generateArticle(spaceId, chatId, publication.id));
|
|
1001
|
+
*
|
|
1002
|
+
* return publication;
|
|
1003
|
+
* }
|
|
1004
|
+
* ```
|
|
1005
|
+
*/
|
|
1006
|
+
declare function onAfterCommit(callback: AfterCommitCallback): void;
|
|
865
1007
|
|
|
866
1008
|
/**
|
|
867
1009
|
* Transaction middleware options
|
|
@@ -942,6 +1084,78 @@ interface TransactionalOptions {
|
|
|
942
1084
|
*/
|
|
943
1085
|
declare function Transactional(options?: TransactionalOptions): hono_types.MiddlewareHandler<any, string, {}, Response>;
|
|
944
1086
|
|
|
1087
|
+
/**
|
|
1088
|
+
* Transaction runner options
|
|
1089
|
+
*/
|
|
1090
|
+
interface RunInTransactionOptions {
|
|
1091
|
+
/**
|
|
1092
|
+
* Slow transaction warning threshold in milliseconds
|
|
1093
|
+
* @default 1000 (1 second)
|
|
1094
|
+
*/
|
|
1095
|
+
slowThreshold?: number;
|
|
1096
|
+
/**
|
|
1097
|
+
* Enable transaction logging
|
|
1098
|
+
* @default true
|
|
1099
|
+
*/
|
|
1100
|
+
enableLogging?: boolean;
|
|
1101
|
+
/**
|
|
1102
|
+
* Transaction timeout in milliseconds
|
|
1103
|
+
*
|
|
1104
|
+
* Sets PostgreSQL `statement_timeout` to enforce database-level timeout.
|
|
1105
|
+
* If transaction exceeds this duration, PostgreSQL will automatically cancel
|
|
1106
|
+
* the query and rollback the transaction, ensuring data consistency.
|
|
1107
|
+
*
|
|
1108
|
+
* Behavior:
|
|
1109
|
+
* - `timeout: 0` - Disables timeout (unlimited execution time)
|
|
1110
|
+
* - `timeout: null` - Uses default (30s or TRANSACTION_TIMEOUT env var)
|
|
1111
|
+
* - `timeout: undefined` - Uses default (30s or TRANSACTION_TIMEOUT env var)
|
|
1112
|
+
* - `timeout: N` - Sets timeout to N milliseconds (1 to 2147483647)
|
|
1113
|
+
*
|
|
1114
|
+
* Note: Timeout is only applied to root transactions. Nested transactions
|
|
1115
|
+
* (SAVEPOINTs) inherit the timeout from the outer transaction.
|
|
1116
|
+
*
|
|
1117
|
+
* @default 30000 (30 seconds) or TRANSACTION_TIMEOUT environment variable
|
|
1118
|
+
*
|
|
1119
|
+
* @example
|
|
1120
|
+
* ```typescript
|
|
1121
|
+
* // Use default timeout (30s)
|
|
1122
|
+
* await runInTransaction(callback);
|
|
1123
|
+
*
|
|
1124
|
+
* // Disable timeout for long-running operations
|
|
1125
|
+
* await runInTransaction(callback, { timeout: 0 });
|
|
1126
|
+
*
|
|
1127
|
+
* // Set custom timeout (60s)
|
|
1128
|
+
* await runInTransaction(callback, { timeout: 60000 });
|
|
1129
|
+
* ```
|
|
1130
|
+
*/
|
|
1131
|
+
timeout?: number;
|
|
1132
|
+
/**
|
|
1133
|
+
* Context string for logging (e.g., 'migration:add-user', 'script:cleanup')
|
|
1134
|
+
* @default 'transaction'
|
|
1135
|
+
*/
|
|
1136
|
+
context?: string;
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Run a callback function within a database transaction
|
|
1140
|
+
*
|
|
1141
|
+
* Automatically manages transaction lifecycle:
|
|
1142
|
+
* - Commits on success
|
|
1143
|
+
* - Rolls back on error
|
|
1144
|
+
* - Tracks execution time
|
|
1145
|
+
* - Warns about slow transactions
|
|
1146
|
+
* - Enforces timeout if configured
|
|
1147
|
+
*
|
|
1148
|
+
* Errors are propagated to the caller without modification.
|
|
1149
|
+
* Caller is responsible for error handling and conversion.
|
|
1150
|
+
*
|
|
1151
|
+
* @param callback - Function to execute within transaction
|
|
1152
|
+
* @param options - Transaction options
|
|
1153
|
+
* @returns Result of callback function
|
|
1154
|
+
* @throws TransactionError if database not initialized or timeout exceeded
|
|
1155
|
+
* @throws Any error thrown by callback function
|
|
1156
|
+
*/
|
|
1157
|
+
declare function runInTransaction<T>(callback: (tx: TransactionDB) => Promise<T>, options?: RunInTransactionOptions): Promise<T>;
|
|
1158
|
+
|
|
945
1159
|
/**
|
|
946
1160
|
* PostgreSQL Error Conversion Utilities
|
|
947
1161
|
*
|
|
@@ -1550,4 +1764,4 @@ declare abstract class BaseRepository<TSchema extends Record<string, unknown> =
|
|
|
1550
1764
|
protected _count<T extends PgTable>(table: T, where?: Record<string, any> | SQL | undefined): Promise<number>;
|
|
1551
1765
|
}
|
|
1552
1766
|
|
|
1553
|
-
export { BaseRepository, type DatabaseClients, type DrizzleConfigOptions, type PoolConfig, RepositoryError, type RetryConfig, type TransactionContext, type TransactionDB, Transactional, type TransactionalOptions, auditFields, checkConnection, closeDatabase, count, create, createDatabaseConnection, createDatabaseFromEnv, createMany, createSchema, deleteMany, deleteOne, detectDialect, enumText, findMany, findOne, foreignKey, fromPostgresError, generateDrizzleConfigFile, getDatabase, getDatabaseInfo, getDrizzleConfig, getSchemaInfo, getTransaction, id, initDatabase, optionalForeignKey, packageNameToSchema, publishingFields, runWithTransaction, setDatabase, softDelete, timestamps, typedJsonb, updateMany, updateOne, upsert, utcTimestamp, uuid, verificationTimestamp };
|
|
1767
|
+
export { type AfterCommitCallback, BaseRepository, type DatabaseClients, type DrizzleConfigOptions, type PoolConfig, RepositoryError, type RetryConfig, type RunInTransactionOptions, type TransactionContext, type TransactionDB, Transactional, type TransactionalOptions, auditFields, checkConnection, closeDatabase, count, create, createDatabaseConnection, createDatabaseFromEnv, createMany, createSchema, deleteMany, deleteOne, detectDialect, enumText, findMany, findOne, forceReconnectDatabase, foreignKey, fromPostgresError, generateDrizzleConfigFile, getDatabase, getDatabaseInfo, getDrizzleConfig, getSchemaInfo, getTransaction, getTransactionContext, id, initDatabase, isConnectionLevelError, onAfterCommit, optionalForeignKey, packageNameToSchema, publishingFields, reportDatabaseError, resetConnectionErrorCounter, runInTransaction, runWithTransaction, setDatabase, softDelete, timestamps, typedJsonb, updateMany, updateOne, upsert, utcTimestamp, uuid, verificationTimestamp };
|