@spfn/core 0.3.0-beta.1 → 0.3.0-beta.10

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.
Files changed (68) hide show
  1. package/README.md +301 -26
  2. package/dist/app-config/index.d.ts +96 -0
  3. package/dist/app-config/index.js +58 -0
  4. package/dist/app-config/index.js.map +1 -0
  5. package/dist/authz/index.js +1 -381
  6. package/dist/authz/index.js.map +1 -1
  7. package/dist/{boss-D16fO2oG.d.ts → boss-BiDCbbAQ.d.ts} +60 -7
  8. package/dist/config/index.d.ts +0 -63
  9. package/dist/config/index.js +12 -12
  10. package/dist/config/index.js.map +1 -1
  11. package/dist/contract/index.d.ts +5 -4
  12. package/dist/db/index.d.ts +201 -34
  13. package/dist/db/index.js +294 -158
  14. package/dist/db/index.js.map +1 -1
  15. package/dist/{define-middleware-DfDP39Nq.d.ts → define-middleware-CVKgqo8S.d.ts} +1 -1
  16. package/dist/env/loader.js +24 -1
  17. package/dist/env/loader.js.map +1 -1
  18. package/dist/errors/index.js +1 -381
  19. package/dist/errors/index.js.map +1 -1
  20. package/dist/event/sse/client.d.ts +15 -2
  21. package/dist/event/sse/client.js +38 -2
  22. package/dist/event/sse/client.js.map +1 -1
  23. package/dist/job/index.d.ts +48 -3
  24. package/dist/job/index.js +118 -40
  25. package/dist/job/index.js.map +1 -1
  26. package/dist/logger/index.js +0 -12
  27. package/dist/logger/index.js.map +1 -1
  28. package/dist/middleware/index.d.ts +6 -2
  29. package/dist/middleware/index.js +7 -388
  30. package/dist/middleware/index.js.map +1 -1
  31. package/dist/nextjs/index.d.ts +37 -1
  32. package/dist/nextjs/index.js +40 -1
  33. package/dist/nextjs/index.js.map +1 -1
  34. package/dist/nextjs/server.d.ts +34 -1
  35. package/dist/nextjs/server.js +14 -0
  36. package/dist/nextjs/server.js.map +1 -1
  37. package/dist/ops/index.d.ts +115 -14
  38. package/dist/ops/index.js +339 -15
  39. package/dist/ops/index.js.map +1 -1
  40. package/dist/route/index.d.ts +5 -3
  41. package/dist/route/index.js +1 -1
  42. package/dist/route/index.js.map +1 -1
  43. package/dist/{router-ukNdAZcN.d.ts → route-builder-2ani2jEI.d.ts} +3 -126
  44. package/dist/router-DJdpwuB6.d.ts +127 -0
  45. package/dist/server/index.d.ts +130 -11
  46. package/dist/server/index.js +714 -70
  47. package/dist/server/index.js.map +1 -1
  48. package/dist/{types-Bvvig_tT.d.ts → types-ClQVomgV.d.ts} +1 -1
  49. package/docs/file-upload.md +195 -333
  50. package/package.json +14 -8
  51. package/src/cache/README.md +330 -0
  52. package/src/codegen/README.md +516 -0
  53. package/src/config/README.md +326 -0
  54. package/src/contract/README.md +326 -0
  55. package/src/db/README.md +589 -0
  56. package/src/db/manager/README.md +500 -0
  57. package/src/db/schema/README.md +354 -0
  58. package/src/db/transaction/README.md +822 -0
  59. package/src/env/README.md +651 -0
  60. package/src/errors/README.md +429 -0
  61. package/src/event/README.md +741 -0
  62. package/src/job/README.md +613 -0
  63. package/src/logger/README.md +321 -0
  64. package/src/middleware/README.md +634 -0
  65. package/src/nextjs/README.md +608 -0
  66. package/src/route/README.md +738 -0
  67. package/src/security/README.md +100 -0
  68. package/src/server/README.md +704 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/schema.ts","../../src/config/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Core Package Environment Variable Schema\n *\n * Centralized schema definition for all environment variables used in @spfn/core.\n * This provides type safety, validation, and documentation for environment configuration.\n *\n * @module config/schema\n */\n\nimport {\n defineEnvSchema,\n envEnum,\n envNumber,\n envBoolean,\n envUrl,\n envString,\n parsePostgresUrl,\n parseRedisUrl,\n} from '@spfn/core/env';\n\n/**\n * Core package environment variable schema\n *\n * Defines all environment variables with:\n * - Type information\n * - Default values\n * - Validation rules\n * - Documentation\n *\n * @example\n * ```typescript\n * import { coreEnvSchema } from '@spfn/core/config';\n *\n * // Access schema information\n * console.log(coreEnvSchema.DB_POOL_MAX.description);\n * console.log(coreEnvSchema.DB_POOL_MAX.default);\n * ```\n */\nexport const coreEnvSchema = defineEnvSchema({\n // ========================================================================\n // Core Environment\n // ========================================================================\n\n NODE_ENV: envEnum(['local', 'development', 'staging', 'production', 'test'] as const, {\n description: 'Node.js runtime environment',\n default: 'local',\n nextjs: true,\n }),\n\n // ========================================================================\n // Database - Connection\n // ========================================================================\n\n DATABASE_URL: envString({\n description: 'Primary database connection URL',\n required: false,\n sensitive: true,\n validator: parsePostgresUrl,\n examples: ['postgresql://user:password@localhost:5432/dbname'],\n }),\n\n DATABASE_WRITE_URL: envString({\n description: 'Write database URL (master-replica pattern)',\n required: false,\n sensitive: true,\n validator: parsePostgresUrl,\n examples: ['postgresql://user:password@master:5432/dbname'],\n }),\n\n DATABASE_READ_URL: envString({\n description: 'Read database URL (master-replica pattern)',\n required: false,\n sensitive: true,\n validator: parsePostgresUrl,\n examples: ['postgresql://user:password@replica:5432/dbname'],\n }),\n\n // ========================================================================\n // Database - Connection Pool\n // ========================================================================\n\n DB_POOL_MAX: envNumber({\n description: 'Maximum number of database connections in pool',\n default: 10,\n examples: [10, 20, 50],\n }),\n\n DB_POOL_READ_MAX: envNumber({\n description: 'Maximum connections for the read-replica pool. Defaults to DB_POOL_MAX. Set lower so write.max + read.max stays under the server max_connections (each process otherwise opens up to 2 × DB_POOL_MAX when a replica is configured).',\n required: false,\n examples: [5, 10, 20],\n }),\n\n DB_POOL_IDLE_TIMEOUT: envNumber({\n description: 'Database connection idle timeout in seconds',\n default: 30,\n examples: [20, 30, 60],\n }),\n\n // ========================================================================\n // Database - Retry Configuration\n // ========================================================================\n\n DB_RETRY_MAX: envNumber({\n description: 'Maximum number of database connection retry attempts',\n default: 3,\n examples: [3, 5, 10],\n }),\n\n DB_RETRY_INITIAL_DELAY: envNumber({\n description: 'Initial delay between database retry attempts (milliseconds)',\n default: 100,\n examples: [50, 100, 200],\n }),\n\n DB_RETRY_MAX_DELAY: envNumber({\n description: 'Maximum delay cap for database retry attempts (milliseconds)',\n default: 10000,\n examples: [5000, 10000, 30000],\n }),\n\n DB_RETRY_FACTOR: envNumber({\n description: 'Exponential backoff factor for database retry delays',\n default: 2,\n examples: [2, 1.5, 3],\n }),\n\n // ========================================================================\n // Database - Health Check\n // ========================================================================\n\n DB_HEALTH_CHECK_ENABLED: envBoolean({\n description: 'Enable periodic database health checks',\n default: true,\n examples: [true, false],\n }),\n\n DB_HEALTH_CHECK_INTERVAL: envNumber({\n description: 'Database health check interval (milliseconds)',\n default: 60000,\n examples: [30000, 60000, 120000],\n }),\n\n DB_HEALTH_CHECK_RECONNECT: envBoolean({\n description: 'Reconnect to database on health check failure',\n default: true,\n examples: [true, false],\n }),\n\n DB_HEALTH_CHECK_MAX_RETRIES: envNumber({\n description: 'Maximum health check retry attempts before marking as failed',\n default: 3,\n examples: [3, 5, 10],\n }),\n\n DB_HEALTH_CHECK_RETRY_INTERVAL: envNumber({\n description: 'Interval between health check retry attempts (milliseconds)',\n default: 5000,\n examples: [5000, 10000, 15000],\n }),\n\n // ========================================================================\n // Database - Monitoring\n // ========================================================================\n\n DB_MONITORING_ENABLED: envBoolean({\n description: 'Enable database query performance monitoring',\n default: false,\n examples: [true, false],\n }),\n\n DB_MONITORING_SLOW_THRESHOLD: envNumber({\n description: 'Slow query threshold for monitoring (milliseconds)',\n default: 1000,\n examples: [500, 1000, 2000],\n }),\n\n DB_MONITORING_LOG_QUERIES: envBoolean({\n description: 'Log all database queries (not just slow queries)',\n default: false,\n examples: [true, false],\n }),\n\n // ========================================================================\n // Database - Transaction\n // ========================================================================\n\n TRANSACTION_TIMEOUT: envNumber({\n description: 'Transaction timeout in milliseconds',\n default: 30000,\n examples: [10000, 30000, 60000],\n }),\n\n TRANSACTION_IDLE_TIMEOUT: envNumber({\n description: 'Max time (ms) a transaction may sit idle (no running query) before Postgres terminates it and reclaims the pooled connection. Guards against external I/O held inside a transaction starving the connection pool. 0 disables.',\n default: 30000,\n examples: [10000, 30000, 0],\n }),\n\n // ========================================================================\n // Jobs (pg-boss)\n // ========================================================================\n\n JOB_POLLING_INTERVAL_SECONDS: envNumber({\n description: 'How often each pg-boss worker polls the DB for new jobs (seconds). Lower = faster pickup, more idle SELECT load; higher = less DB chatter, slower pickup. Per-job override via job options.',\n default: 2,\n examples: [1, 2, 10],\n }),\n\n // ========================================================================\n // Database - Development\n // ========================================================================\n\n DB_DEBUG_TRACE: envBoolean({\n description: 'Enable detailed debug tracing for database operations',\n default: false,\n examples: [true, false],\n }),\n\n // ========================================================================\n // Database - Migrations\n // ========================================================================\n\n SPFN_ALLOW_PENDING_MIGRATIONS: envBoolean({\n description: 'Start the server even when a function package or the project has migrations the database has not applied. Off by default: a server booted with pending migrations fails only at request time, as an opaque 500. The flag equivalent is `spfn dev --allow-pending-migrations`.',\n default: false,\n examples: [true, false],\n }),\n\n // ========================================================================\n // Drizzle ORM\n // ========================================================================\n\n DRIZZLE_SCHEMA_PATH: envString({\n description: 'Path to Drizzle schema configuration',\n required: false,\n default: './src/server/entities/config.ts',\n examples: ['./src/db/schema.ts', './src/server/entities/config.ts'],\n }),\n\n DRIZZLE_OUT_DIR: envString({\n description: 'Output directory for Drizzle migrations',\n required: false,\n default: './drizzle',\n examples: ['./drizzle', './migrations'],\n }),\n\n // ========================================================================\n // Logger - Core\n // ========================================================================\n\n SPFN_LOG_LEVEL: envEnum(['debug', 'info', 'warn', 'error', 'fatal'] as const, {\n description: 'Minimum log level to output',\n default: 'info',\n }),\n\n // ========================================================================\n // Cache (Redis/Valkey)\n // ========================================================================\n\n CACHE_URL: envString({\n description: 'Single Redis/Valkey instance URL',\n required: false,\n sensitive: true,\n validator: parseRedisUrl,\n examples: ['redis://localhost:6379', 'rediss://secure.cache.com:6380'],\n }),\n\n CACHE_WRITE_URL: envString({\n description: 'Master Redis/Valkey URL for writes (master-replica pattern)',\n required: false,\n sensitive: true,\n validator: parseRedisUrl,\n examples: ['redis://master:6379'],\n }),\n\n CACHE_READ_URL: envString({\n description: 'Replica Redis/Valkey URL for reads (master-replica pattern)',\n required: false,\n sensitive: true,\n validator: parseRedisUrl,\n examples: ['redis://replica:6379'],\n }),\n\n CACHE_SENTINEL_HOSTS: envString({\n description: 'Comma-separated Redis Sentinel hosts',\n required: false,\n examples: ['sentinel1:26379,sentinel2:26379'],\n }),\n\n CACHE_CLUSTER_NODES: envString({\n description: 'Comma-separated Redis Cluster nodes',\n required: false,\n examples: ['node1:6379,node2:6379,node3:6379'],\n }),\n\n CACHE_MASTER_NAME: envString({\n description: 'Redis Sentinel master name',\n required: false,\n examples: ['mymaster'],\n }),\n\n CACHE_PASSWORD: envString({\n description: 'Redis/Valkey authentication password',\n required: false,\n sensitive: true,\n examples: ['your-redis-password'],\n }),\n\n CACHE_TLS_REJECT_UNAUTHORIZED: envBoolean({\n description: 'Verify TLS certificates for secure Redis connections',\n default: true,\n examples: [true, false],\n }),\n\n CACHE_MAX_RETRIES_PER_REQUEST: envNumber({\n description: 'Max ioredis retries per command before it rejects (fail fast instead of hanging on a cache outage). ioredis default is 20.',\n default: 3,\n examples: [1, 3, 20],\n }),\n\n CACHE_ENABLE_OFFLINE_QUEUE: envBoolean({\n description: 'Queue commands while the cache is disconnected (true) vs reject immediately for strict fail-fast (false). Default true keeps resilience to brief blips.',\n default: true,\n examples: [true, false],\n }),\n\n // ========================================================================\n // Database - Query limits\n // ========================================================================\n\n DB_MAX_ROWS: envNumber({\n description: 'Safety ceiling for rows returned by repository findMany (0 = unlimited). When >0, an unbounded query is capped and an explicit limit is clamped, guarding against accidentally loading a whole large table.',\n default: 0,\n examples: [0, 1000, 10000],\n }),\n\n // ========================================================================\n // Server - Core\n // ========================================================================\n\n PORT: envNumber({\n description: 'Server port number',\n default: 4000,\n examples: [3000, 4000, 8080],\n }),\n\n HOST: envString({\n description: 'Server hostname',\n default: 'localhost',\n required: false,\n examples: ['localhost', '0.0.0.0', '127.0.0.1'],\n }),\n\n // ========================================================================\n // Server - Timeout\n // ========================================================================\n\n SERVER_TIMEOUT: envNumber({\n description: 'Request timeout in milliseconds',\n default: 120000,\n examples: [60000, 120000, 300000],\n }),\n\n SERVER_KEEPALIVE_TIMEOUT: envNumber({\n description: 'Keep-alive timeout in milliseconds',\n default: 65000,\n examples: [30000, 65000, 120000],\n }),\n\n SERVER_HEADERS_TIMEOUT: envNumber({\n description: 'Headers timeout in milliseconds',\n default: 60000,\n examples: [30000, 60000, 120000],\n }),\n\n SHUTDOWN_TIMEOUT: envNumber({\n description: 'Graceful shutdown timeout in milliseconds (must be less than k8s terminationGracePeriodSeconds minus preStop sleep, with safety margin)',\n default: 280000,\n examples: [30000, 120000, 280000],\n }),\n\n // ========================================================================\n // Fetch (Node.js undici) - outbound HTTP request timeout\n // ========================================================================\n\n FETCH_CONNECT_TIMEOUT: envNumber({\n description: 'Fetch TCP connection timeout in milliseconds (time to establish socket connection to upstream server)',\n default: 10000,\n examples: [5000, 10000, 30000],\n }),\n\n FETCH_HEADERS_TIMEOUT: envNumber({\n description: 'Fetch headers timeout in milliseconds (time to receive response headers after request sent)',\n default: 300000,\n examples: [120000, 300000, 600000],\n }),\n\n FETCH_BODY_TIMEOUT: envNumber({\n description: 'Fetch body timeout in milliseconds (time between body data chunks from upstream server)',\n default: 300000,\n examples: [120000, 300000, 600000],\n }),\n\n // ========================================================================\n // Next.js Integration\n // ========================================================================\n\n SPFN_API_URL: envUrl({\n description: 'SPFN API URL (used by Next.js to call backend)',\n required: true,\n nextjs: true,\n examples: ['http://localhost:8790', 'https://api.your-app.com'],\n }),\n\n NEXT_PUBLIC_SPFN_API_URL: envUrl({\n description: 'SPFN API URL (used by Next.js to call backend)',\n required: true,\n nextjs: true,\n examples: ['http://localhost:8790', 'https://api.your-app.com'],\n }),\n\n SPFN_APP_URL: envUrl({\n description: 'Next.js application URL (used by SPFN server)',\n required: false,\n nextjs: true,\n examples: ['http://localhost:3790', 'https://your-app.com'],\n }),\n\n RPC_PROXY_TIMEOUT: envNumber({\n description: 'RPC proxy request timeout in milliseconds (AbortController timeout for proxied requests to backend, should be shorter than FETCH_HEADERS_TIMEOUT)',\n default: 120000,\n nextjs: true,\n examples: [60000, 120000, 280000],\n }),\n\n // ========================================================================\n // Proxy → Backend trust (HMAC signing)\n // ========================================================================\n\n SPFN_PROXY_SECRET: envString({\n description: 'Shared secret for signing proxy→backend requests (HMAC-SHA256). Read by BOTH processes — the Next.js proxy (to sign) and the SPFN backend (to verify) — so it belongs in .env.local (loaded by both; the backend reads it via loadEnv, Next.js reads it server-side without exposing it to the browser). Set the SAME value on both. Leave unset to disable proxy-guard signing.',\n required: false,\n sensitive: true,\n nextjs: true,\n examples: ['<32+ byte random hex>', 'v2:<32+ byte random hex>'],\n }),\n\n SPFN_PROXY_SECRET_PREVIOUS: envString({\n description: 'Previous (grace) proxy keys still accepted for verification during rotation — comma-separated <keyId>:<secret>. The proxy never signs with these; they only keep requests signed with the prior key verifying until a rollout settles. Backend-only (verification), so it belongs in .env.server, NOT exposed to the Next.js process.',\n required: false,\n sensitive: true,\n nextjs: false,\n examples: ['v1:<old secret>', 'v1:<old>,v0:<older>'],\n }),\n\n TRUSTED_PROXY_HOPS: envNumber({\n description: 'Number of trusted reverse proxies in front of the Next.js proxy (e.g. cloud LB + nginx = 2). Read by the proxy to extract the real client IP from the inbound X-Forwarded-For (counting from the right, which your own infra appends and a client cannot spoof) and forward it to the backend for rate limiting. Set it to your actual hop count; too low trusts a client-spoofable entry, too high collapses users behind a shared proxy IP.',\n default: 1,\n nextjs: true,\n examples: [1, 2, 3],\n }),\n\n // ========================================================================\n // Rate limiting (global default limiter)\n // ========================================================================\n\n RATE_LIMIT_MODE: envEnum(['off', 'on'] as const, {\n description: 'Global default rate limiter. \"off\": only routes tagged with rateLimitPolicy() are limited. \"on\": every named-middleware route gets the default limit too (opt out per route with .skip([\\'rateLimit\\'])). Health/SSE/WebSocket endpoints are always exempt. Overridden by defineServerConfig().rateLimit({ mode }).',\n default: 'off',\n }),\n\n RATE_LIMIT_DEFAULT_LIMIT: envNumber({\n description: 'Max requests per window for the global default limiter (RATE_LIMIT_MODE=on), counted per route and per client IP.',\n default: 100,\n examples: [60, 100, 300],\n }),\n\n RATE_LIMIT_DEFAULT_WINDOW_MS: envNumber({\n description: 'Window length in milliseconds for the global default limiter.',\n default: 60000,\n examples: [1000, 60000],\n }),\n\n RATE_LIMIT_FAIL_CLOSED: envBoolean({\n description: 'When the cache (Redis/Valkey) backing the limiter is unavailable, reject with 429 instead of counting in-process. Default false: the limiter falls back to per-process counters, so limits still apply — but the effective limit multiplies by the instance count, since each process counts alone. Set true only where a shared count is required and refusing traffic is preferable to a looser one.',\n default: false,\n }),\n\n // ========================================================================\n // Outbound request safety (SSRF)\n // ========================================================================\n\n SAFE_FETCH_BLOCK_PRIVATE_IPS: envBoolean({\n description: 'Default for safeFetch (@spfn/core/security): block outbound requests that resolve to private/reserved IP ranges, including the cloud metadata address. Keep true in production; set false only for trusted internal-network calls in development. Overridden by defineServerConfig().outboundFetch({ blockPrivateIps }).',\n default: true,\n }),\n});\n","/**\n * Core Package Configuration\n *\n * @example\n * ```typescript\n * import { registry } from '@spfn/core/config';\n *\n * const env = registry.validate();\n * console.log(env.DB_POOL_MAX);\n * ```\n *\n * @module config\n */\n\nimport { createEnvRegistry } from '@spfn/core/env';\nimport { coreEnvSchema } from './schema';\n\n/**\n * Core environment schema\n */\nexport { coreEnvSchema as envSchema } from './schema';\n\n/**\n * Environment registry\n *\n * @example\n * ```typescript\n * // Reset for testing\n * registry.reset();\n * ```\n */\nexport const registry = createEnvRegistry(coreEnvSchema);\n\n/**\n * Validated environment configuration\n */\nexport const env = registry.validate();\n"]}
1
+ {"version":3,"sources":["../../src/config/schema.ts","../../src/config/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Core Package Environment Variable Schema\n *\n * Centralized schema definition for all environment variables used in @spfn/core.\n * This provides type safety, validation, and documentation for environment configuration.\n *\n * @module config/schema\n */\n\nimport {\n defineEnvSchema,\n envEnum,\n envNumber,\n envBoolean,\n envUrl,\n envString,\n parsePostgresUrl,\n parseRedisUrl,\n} from '@spfn/core/env';\n\n/**\n * Core package environment variable schema\n *\n * Defines all environment variables with:\n * - Type information\n * - Default values\n * - Validation rules\n * - Documentation\n *\n * @example\n * ```typescript\n * import { coreEnvSchema } from '@spfn/core/config';\n *\n * // Access schema information\n * console.log(coreEnvSchema.DB_POOL_MAX.description);\n * console.log(coreEnvSchema.DB_POOL_MAX.default);\n * ```\n */\nexport const coreEnvSchema = defineEnvSchema({\n // ========================================================================\n // Core Environment\n // ========================================================================\n\n NODE_ENV: envEnum(['local', 'development', 'staging', 'production', 'test'] as const, {\n description: 'Node.js runtime environment',\n default: 'local',\n nextjs: true,\n }),\n\n // ========================================================================\n // Database - Connection\n // ========================================================================\n\n DATABASE_URL: envString({\n description: 'Primary database connection URL',\n required: false,\n sensitive: true,\n validator: parsePostgresUrl,\n examples: ['postgresql://user:password@localhost:5432/dbname'],\n }),\n\n DATABASE_WRITE_URL: envString({\n description: 'Write database URL (master-replica pattern)',\n required: false,\n sensitive: true,\n validator: parsePostgresUrl,\n examples: ['postgresql://user:password@master:5432/dbname'],\n }),\n\n DATABASE_READ_URL: envString({\n description: 'Read database URL (master-replica pattern)',\n required: false,\n sensitive: true,\n validator: parsePostgresUrl,\n examples: ['postgresql://user:password@replica:5432/dbname'],\n }),\n\n // ========================================================================\n // Database - Connection Pool\n // ========================================================================\n\n DB_POOL_MAX: envNumber({\n description: 'Maximum number of database connections in pool',\n default: 10,\n examples: [10, 20, 50],\n }),\n\n DB_POOL_READ_MAX: envNumber({\n description: 'Maximum connections for the read-replica pool. Defaults to DB_POOL_MAX. Set lower so write.max + read.max stays under the server max_connections (each process otherwise opens up to 2 × DB_POOL_MAX when a replica is configured).',\n required: false,\n examples: [5, 10, 20],\n }),\n\n DB_POOL_IDLE_TIMEOUT: envNumber({\n description: 'Database connection idle timeout in seconds',\n default: 30,\n examples: [20, 30, 60],\n }),\n\n // ========================================================================\n // Database - Retry Configuration\n // ========================================================================\n\n DB_RETRY_MAX: envNumber({\n description: 'Maximum number of database connection retry attempts',\n default: 3,\n examples: [3, 5, 10],\n }),\n\n DB_RETRY_INITIAL_DELAY: envNumber({\n description: 'Initial delay between database retry attempts (milliseconds)',\n default: 100,\n examples: [50, 100, 200],\n }),\n\n DB_RETRY_MAX_DELAY: envNumber({\n description: 'Maximum delay cap for database retry attempts (milliseconds)',\n default: 10000,\n examples: [5000, 10000, 30000],\n }),\n\n DB_RETRY_FACTOR: envNumber({\n description: 'Exponential backoff factor for database retry delays',\n default: 2,\n examples: [2, 1.5, 3],\n }),\n\n // ========================================================================\n // Database - Health Check\n // ========================================================================\n\n DB_HEALTH_CHECK_ENABLED: envBoolean({\n description: 'Enable periodic database health checks',\n default: true,\n examples: [true, false],\n }),\n\n DB_HEALTH_CHECK_INTERVAL: envNumber({\n description: 'Database health check interval (milliseconds)',\n default: 60000,\n examples: [30000, 60000, 120000],\n }),\n\n DB_HEALTH_CHECK_RECONNECT: envBoolean({\n description: 'Reconnect to database on health check failure',\n default: true,\n examples: [true, false],\n }),\n\n DB_HEALTH_CHECK_MAX_RETRIES: envNumber({\n description: 'Maximum health check retry attempts before marking as failed',\n default: 3,\n examples: [3, 5, 10],\n }),\n\n DB_HEALTH_CHECK_RETRY_INTERVAL: envNumber({\n description: 'Interval between health check retry attempts (milliseconds)',\n default: 5000,\n examples: [5000, 10000, 15000],\n }),\n\n // ========================================================================\n // Database - Monitoring\n // ========================================================================\n\n DB_MONITORING_ENABLED: envBoolean({\n description: 'Enable database query performance monitoring',\n default: false,\n examples: [true, false],\n }),\n\n DB_MONITORING_SLOW_THRESHOLD: envNumber({\n description: 'Slow query threshold for monitoring (milliseconds)',\n default: 1000,\n examples: [500, 1000, 2000],\n }),\n\n DB_MONITORING_LOG_QUERIES: envBoolean({\n description: 'Log all database queries (not just slow queries)',\n default: false,\n examples: [true, false],\n }),\n\n // ========================================================================\n // Database - Transaction\n // ========================================================================\n\n TRANSACTION_TIMEOUT: envNumber({\n description: 'Transaction timeout in milliseconds',\n default: 30000,\n examples: [10000, 30000, 60000],\n }),\n\n TRANSACTION_IDLE_TIMEOUT: envNumber({\n description: 'Max time (ms) a transaction may sit idle (no running query) before Postgres terminates it and reclaims the pooled connection. Guards against external I/O held inside a transaction starving the connection pool. 0 disables.',\n default: 30000,\n examples: [10000, 30000, 0],\n }),\n\n // ========================================================================\n // Jobs (pg-boss)\n // ========================================================================\n\n JOB_POLLING_INTERVAL_SECONDS: envNumber({\n description: 'How often each pg-boss worker polls the DB for new jobs (seconds). Lower = faster pickup, more idle SELECT load; higher = less DB chatter, slower pickup. Per-job override via job options.',\n default: 2,\n examples: [1, 2, 10],\n }),\n\n // ========================================================================\n // Database - Development\n // ========================================================================\n\n DB_DEBUG_TRACE: envBoolean({\n description: 'Enable detailed debug tracing for database operations',\n default: false,\n examples: [true, false],\n }),\n\n // ========================================================================\n // Database - Migrations\n // ========================================================================\n\n SPFN_ALLOW_PENDING_MIGRATIONS: envBoolean({\n description: 'Start the server even when a function package or the project has migrations the database has not applied. Off by default: a server booted with pending migrations fails only at request time, as an opaque 500. The flag equivalent is `spfn dev --allow-pending-migrations`.',\n default: false,\n examples: [true, false],\n }),\n\n // ========================================================================\n // Drizzle ORM\n // ========================================================================\n\n DRIZZLE_SCHEMA_PATH: envString({\n description: 'Entity registry file spfn db push/generate/studio load when src/server/entities/ holds no entity file, or when the registry exports a table no file there defines',\n required: false,\n default: './src/server/entities/config.ts',\n examples: ['./src/db/schema.ts', './src/server/entities/config.ts'],\n }),\n\n DRIZZLE_OUT_DIR: envString({\n description: 'Output directory for Drizzle migrations',\n required: false,\n default: './drizzle',\n examples: ['./drizzle', './migrations'],\n }),\n\n // ========================================================================\n // Logger - Core\n // ========================================================================\n\n SPFN_LOG_LEVEL: envEnum(['debug', 'info', 'warn', 'error', 'fatal'] as const, {\n description: 'Minimum log level to output',\n default: 'info',\n }),\n\n // ========================================================================\n // Cache (Redis/Valkey)\n // ========================================================================\n\n CACHE_URL: envString({\n description: 'Single Redis/Valkey instance URL',\n required: false,\n sensitive: true,\n validator: parseRedisUrl,\n examples: ['redis://localhost:6379', 'rediss://secure.cache.com:6380'],\n }),\n\n CACHE_WRITE_URL: envString({\n description: 'Master Redis/Valkey URL for writes (master-replica pattern)',\n required: false,\n sensitive: true,\n validator: parseRedisUrl,\n examples: ['redis://master:6379'],\n }),\n\n CACHE_READ_URL: envString({\n description: 'Replica Redis/Valkey URL for reads (master-replica pattern)',\n required: false,\n sensitive: true,\n validator: parseRedisUrl,\n examples: ['redis://replica:6379'],\n }),\n\n CACHE_SENTINEL_HOSTS: envString({\n description: 'Comma-separated Redis Sentinel hosts',\n required: false,\n examples: ['sentinel1:26379,sentinel2:26379'],\n }),\n\n CACHE_CLUSTER_NODES: envString({\n description: 'Comma-separated Redis Cluster nodes',\n required: false,\n examples: ['node1:6379,node2:6379,node3:6379'],\n }),\n\n CACHE_MASTER_NAME: envString({\n description: 'Redis Sentinel master name',\n required: false,\n examples: ['mymaster'],\n }),\n\n CACHE_PASSWORD: envString({\n description: 'Redis/Valkey authentication password',\n required: false,\n sensitive: true,\n examples: ['your-redis-password'],\n }),\n\n CACHE_TLS_REJECT_UNAUTHORIZED: envBoolean({\n description: 'Verify TLS certificates for secure Redis connections',\n default: true,\n examples: [true, false],\n }),\n\n CACHE_MAX_RETRIES_PER_REQUEST: envNumber({\n description: 'Max ioredis retries per command before it rejects (fail fast instead of hanging on a cache outage). ioredis default is 20.',\n default: 3,\n examples: [1, 3, 20],\n }),\n\n CACHE_ENABLE_OFFLINE_QUEUE: envBoolean({\n description: 'Queue commands while the cache is disconnected (true) vs reject immediately for strict fail-fast (false). Default true keeps resilience to brief blips.',\n default: true,\n examples: [true, false],\n }),\n\n // ========================================================================\n // Database - Query limits\n // ========================================================================\n\n DB_MAX_ROWS: envNumber({\n description: 'Safety ceiling for rows returned by repository findMany (0 = unlimited). When >0, an unbounded query is capped and an explicit limit is clamped, guarding against accidentally loading a whole large table.',\n default: 0,\n examples: [0, 1000, 10000],\n }),\n\n // ========================================================================\n // Server - Core\n // ========================================================================\n\n // PORT and HOST are deliberately absent.\n //\n // They were declared here with defaults of 4000 and 'localhost', and a\n // schema default is indistinguishable from a value someone set — so\n // `env.PORT` was never undefined, and the resolution order had to consult\n // the environment last to avoid it winning every time. That is what made an\n // injected port unreachable. The server's address now resolves through\n // `@spfn/core/app-config`: SPFN_PORT, then spfn.config.js, then the\n // default, with the default existing in exactly one place.\n //\n // `PORT` is also Next.js's own variable, and two processes are started.\n\n // ========================================================================\n // Server - Timeout\n // ========================================================================\n\n SERVER_TIMEOUT: envNumber({\n description: 'Request timeout in milliseconds',\n default: 120000,\n examples: [60000, 120000, 300000],\n }),\n\n SERVER_KEEPALIVE_TIMEOUT: envNumber({\n description: 'Keep-alive timeout in milliseconds',\n default: 65000,\n examples: [30000, 65000, 120000],\n }),\n\n SERVER_HEADERS_TIMEOUT: envNumber({\n description: 'Headers timeout in milliseconds',\n default: 60000,\n examples: [30000, 60000, 120000],\n }),\n\n SHUTDOWN_TIMEOUT: envNumber({\n description: 'Graceful shutdown timeout in milliseconds (must be less than k8s terminationGracePeriodSeconds minus preStop sleep, with safety margin)',\n default: 280000,\n examples: [30000, 120000, 280000],\n }),\n\n // ========================================================================\n // Fetch (Node.js undici) - outbound HTTP request timeout\n // ========================================================================\n\n FETCH_CONNECT_TIMEOUT: envNumber({\n description: 'Fetch TCP connection timeout in milliseconds (time to establish socket connection to upstream server)',\n default: 10000,\n examples: [5000, 10000, 30000],\n }),\n\n FETCH_HEADERS_TIMEOUT: envNumber({\n description: 'Fetch headers timeout in milliseconds (time to receive response headers after request sent)',\n default: 300000,\n examples: [120000, 300000, 600000],\n }),\n\n FETCH_BODY_TIMEOUT: envNumber({\n description: 'Fetch body timeout in milliseconds (time between body data chunks from upstream server)',\n default: 300000,\n examples: [120000, 300000, 600000],\n }),\n\n // ========================================================================\n // Next.js Integration\n // ========================================================================\n\n SPFN_API_URL: envUrl({\n description: 'SPFN API URL (used by Next.js to call backend)',\n required: true,\n nextjs: true,\n examples: ['http://localhost:8790', 'https://api.your-app.com'],\n }),\n\n NEXT_PUBLIC_SPFN_API_URL: envUrl({\n description: 'SPFN API URL (used by Next.js to call backend)',\n required: true,\n nextjs: true,\n examples: ['http://localhost:8790', 'https://api.your-app.com'],\n }),\n\n SPFN_APP_URL: envUrl({\n description: 'Next.js application URL (used by SPFN server)',\n required: false,\n nextjs: true,\n examples: ['http://localhost:3790', 'https://your-app.com'],\n }),\n\n RPC_PROXY_TIMEOUT: envNumber({\n description: 'RPC proxy request timeout in milliseconds (AbortController timeout for proxied requests to backend, should be shorter than FETCH_HEADERS_TIMEOUT)',\n default: 120000,\n nextjs: true,\n examples: [60000, 120000, 280000],\n }),\n\n // ========================================================================\n // Proxy → Backend trust (HMAC signing)\n // ========================================================================\n\n SPFN_PROXY_SECRET: envString({\n description: 'Shared secret for signing proxy→backend requests (HMAC-SHA256). Read by BOTH processes — the Next.js proxy (to sign) and the SPFN backend (to verify) — so it belongs in .env.local (loaded by both; the backend reads it via loadEnv, Next.js reads it server-side without exposing it to the browser). Set the SAME value on both. Leave unset to disable proxy-guard signing.',\n required: false,\n sensitive: true,\n nextjs: true,\n examples: ['<32+ byte random hex>', 'v2:<32+ byte random hex>'],\n }),\n\n SPFN_PROXY_SECRET_PREVIOUS: envString({\n description: 'Previous (grace) proxy keys still accepted for verification during rotation — comma-separated <keyId>:<secret>. The proxy never signs with these; they only keep requests signed with the prior key verifying until a rollout settles. Backend-only (verification), so it belongs in .env.server, NOT exposed to the Next.js process.',\n required: false,\n sensitive: true,\n nextjs: false,\n examples: ['v1:<old secret>', 'v1:<old>,v0:<older>'],\n }),\n\n TRUSTED_PROXY_HOPS: envNumber({\n description: 'Number of trusted reverse proxies in front of the Next.js proxy (e.g. cloud LB + nginx = 2). Read by the proxy to extract the real client IP from the inbound X-Forwarded-For (counting from the right, which your own infra appends and a client cannot spoof) and forward it to the backend for rate limiting. Set it to your actual hop count; too low trusts a client-spoofable entry, too high collapses users behind a shared proxy IP.',\n default: 1,\n nextjs: true,\n examples: [1, 2, 3],\n }),\n\n // ========================================================================\n // Rate limiting (global default limiter)\n // ========================================================================\n\n RATE_LIMIT_MODE: envEnum(['off', 'on'] as const, {\n description: 'Global default rate limiter. \"off\": only routes tagged with rateLimitPolicy() are limited. \"on\": every named-middleware route gets the default limit too (opt out per route with .skip([\\'rateLimit\\'])). Health/SSE/WebSocket endpoints are always exempt. Overridden by defineServerConfig().rateLimit({ mode }).',\n default: 'off',\n }),\n\n RATE_LIMIT_DEFAULT_LIMIT: envNumber({\n description: 'Max requests per window for the global default limiter (RATE_LIMIT_MODE=on), counted per route and per client IP.',\n default: 100,\n examples: [60, 100, 300],\n }),\n\n RATE_LIMIT_DEFAULT_WINDOW_MS: envNumber({\n description: 'Window length in milliseconds for the global default limiter.',\n default: 60000,\n examples: [1000, 60000],\n }),\n\n RATE_LIMIT_FAIL_CLOSED: envBoolean({\n description: 'When the cache (Redis/Valkey) backing the limiter is unavailable, reject with 429 instead of counting in-process. Default false: the limiter falls back to per-process counters, so limits still apply — but the effective limit multiplies by the instance count, since each process counts alone. Set true only where a shared count is required and refusing traffic is preferable to a looser one.',\n default: false,\n }),\n\n // ========================================================================\n // Outbound request safety (SSRF)\n // ========================================================================\n\n SAFE_FETCH_BLOCK_PRIVATE_IPS: envBoolean({\n description: 'Default for safeFetch (@spfn/core/security): block outbound requests that resolve to private/reserved IP ranges, including the cloud metadata address. Keep true in production; set false only for trusted internal-network calls in development. Overridden by defineServerConfig().outboundFetch({ blockPrivateIps }).',\n default: true,\n }),\n});\n","/**\n * Core Package Configuration\n *\n * @example\n * ```typescript\n * import { registry } from '@spfn/core/config';\n *\n * const env = registry.validate();\n * console.log(env.DB_POOL_MAX);\n * ```\n *\n * @module config\n */\n\nimport { createEnvRegistry } from '@spfn/core/env';\nimport { coreEnvSchema } from './schema';\n\n/**\n * Core environment schema\n */\nexport { coreEnvSchema as envSchema } from './schema';\n\n/**\n * Environment registry\n *\n * @example\n * ```typescript\n * // Reset for testing\n * registry.reset();\n * ```\n */\nexport const registry = createEnvRegistry(coreEnvSchema);\n\n/**\n * Validated environment configuration\n */\nexport const env = registry.validate();\n"]}
@@ -1,8 +1,9 @@
1
- import { R as Router } from '../router-ukNdAZcN.js';
2
- import { C as ContractDocument, a as ContractViolation, b as ContractOperation, c as ContractSnapshot } from '../types-Bvvig_tT.js';
3
- export { d as CompatibilityPolicy, e as ContractRequest, f as ContractViolationKind, J as JsonSchema } from '../types-Bvvig_tT.js';
4
- import '../define-middleware-DfDP39Nq.js';
1
+ import { R as Router } from '../router-DJdpwuB6.js';
2
+ import { C as ContractDocument, a as ContractViolation, b as ContractOperation, c as ContractSnapshot } from '../types-ClQVomgV.js';
3
+ export { d as CompatibilityPolicy, e as ContractRequest, f as ContractViolationKind, J as JsonSchema } from '../types-ClQVomgV.js';
4
+ import '../define-middleware-CVKgqo8S.js';
5
5
  import 'hono';
6
+ import '../route-builder-2ani2jEI.js';
6
7
  import '@sinclair/typebox';
7
8
  import 'hono/utils/http-status';
8
9
  import '../route/types.js';
@@ -246,7 +246,7 @@ declare function getDatabase<TDatabase extends DrizzleDatabase = DefaultDatabase
246
246
  * // Set custom database instances (testing)
247
247
  * const writeClient = postgres('postgresql://primary:5432/mydb');
248
248
  * const readClient = postgres('postgresql://replica:5432/mydb');
249
- * setDatabase(drizzle(writeClient), drizzle(readClient));
249
+ * setDatabase(drizzle({ client: writeClient }), drizzle({ client: readClient }));
250
250
  *
251
251
  * // Clear instances (not recommended - use closeDatabase() instead)
252
252
  * setDatabase(undefined, undefined);
@@ -397,27 +397,6 @@ declare function getDatabaseInfo(): {
397
397
  providerKind?: string;
398
398
  };
399
399
 
400
- /**
401
- * Reconnect Trigger — Query-error driven pool rebuild
402
- *
403
- * Complements the periodic health check with a fast-path: when application
404
- * queries start failing with connection-level errors, we do not wait up to
405
- * DB_HEALTH_CHECK_INTERVAL (default 60s) to notice. A sliding-window counter
406
- * trips a force-reconnect as soon as the failure rate crosses a threshold.
407
- *
408
- * Why this exists:
409
- * - postgres.js transparently drops dead sockets and opens new ones on the
410
- * next query. A single `SELECT 1` on the periodic interval can therefore
411
- * false-pass while user-facing queries keep hitting the remaining dead
412
- * sockets in the pool.
413
- * - This module observes real query errors and, when it sees a burst of
414
- * connection-level failures, calls triggerForceReconnect() which performs
415
- * the same atomic-swap rebuild as the health check.
416
- *
417
- * Configuration (env vars, hardcoded defaults):
418
- * - DB_RECONNECT_ERROR_THRESHOLD (default 3): errors needed in window
419
- * - DB_RECONNECT_ERROR_WINDOW_MS (default 10000): sliding window size
420
- */
421
400
  /**
422
401
  * Determine whether an error looks like a pool/connection failure
423
402
  *
@@ -505,7 +484,7 @@ declare function checkConnection(client: Sql): Promise<boolean>;
505
484
  interface DrizzleConfigOptions {
506
485
  /** Database connection URL (defaults to process.env.DATABASE_URL) */
507
486
  databaseUrl?: string;
508
- /** Schema files glob pattern or array of patterns (defaults to './src/server/entities/\*\*\/*.ts') */
487
+ /** Schema entry file(s), directories or glob pattern(s). Default: './src/server/entities/\*\*\/*.ts', or the registry `DRIZZLE_SCHEMA_PATH` (./src/server/entities/config.ts) when that scan finds no entity file; `schemaRegistry` reports the registry when both exist */
509
488
  schema?: string | string[];
510
489
  /** Migration output directory (defaults to './src/server/drizzle') */
511
490
  out?: string;
@@ -521,8 +500,6 @@ interface DrizzleConfigOptions {
521
500
  expandGlobs?: boolean;
522
501
  /** PostgreSQL schema filter for push/introspect commands */
523
502
  schemaFilter?: string[];
524
- /** Auto-detect PostgreSQL schemas from entity files (requires expandGlobs: true) */
525
- autoDetectSchemas?: boolean;
526
503
  /** Migration prefix strategy (default: 'timestamp') */
527
504
  migrationPrefix?: 'index' | 'timestamp' | 'unix' | 'none';
528
505
  }
@@ -551,6 +528,8 @@ declare function detectDialect(url: string): 'postgresql' | 'mysql' | 'sqlite';
551
528
  */
552
529
  declare function getDrizzleConfig(options?: DrizzleConfigOptions): {
553
530
  schema: string | string[];
531
+ schemaSource: string;
532
+ schemaRegistry: string | undefined;
554
533
  out: string;
555
534
  dialect: "postgresql" | "mysql" | "sqlite";
556
535
  dbCredentials: {
@@ -562,6 +541,8 @@ declare function getDrizzleConfig(options?: DrizzleConfigOptions): {
562
541
  schemaFilter?: undefined;
563
542
  } | {
564
543
  schema: string | string[];
544
+ schemaSource: string;
545
+ schemaRegistry: string | undefined;
565
546
  out: string;
566
547
  dialect: "postgresql" | "mysql" | "sqlite";
567
548
  dbCredentials: {
@@ -573,10 +554,29 @@ declare function getDrizzleConfig(options?: DrizzleConfigOptions): {
573
554
  };
574
555
  };
575
556
  /**
576
- * Generate drizzle.config.ts file content
557
+ * The schema fields a rendered drizzle.config.ts needs
558
+ */
559
+ interface RenderableDrizzleConfig {
560
+ schema: string | string[];
561
+ out: string;
562
+ dialect: string;
563
+ dbCredentials: Record<string, unknown>;
564
+ schemaFilter?: string[];
565
+ migrations?: Record<string, unknown>;
566
+ }
567
+ /**
568
+ * Render an already-resolved config as drizzle.config.ts source, schema
569
+ * paths made absolute for Drizzle Studio
577
570
  *
578
- * @param options - Configuration options
579
- * @returns File content as string
571
+ * @param config - Result of getDrizzleConfig, possibly with the schema replaced
572
+ * @param cwd - Base for relative schema paths (default: process.cwd())
573
+ */
574
+ declare function renderDrizzleConfig(config: RenderableDrizzleConfig, cwd?: string): string;
575
+ /**
576
+ * Generate drizzle.config.ts source from options: resolve the config, then render it
577
+ *
578
+ * @param options - Configuration options (see getDrizzleConfig)
579
+ * @returns drizzle.config.ts source
580
580
  */
581
581
  declare function generateDrizzleConfigFile(options?: DrizzleConfigOptions): string;
582
582
 
@@ -1139,6 +1139,23 @@ type TransactionDB<TDatabase extends DrizzleDatabase = DefaultDatabase> = Databa
1139
1139
  * afterCommit callback type
1140
1140
  */
1141
1141
  type AfterCommitCallback = () => void | Promise<void>;
1142
+ /**
1143
+ * beforeCommit callback type
1144
+ */
1145
+ type BeforeCommitCallback = () => void | Promise<void>;
1146
+ /**
1147
+ * afterRollback callback type
1148
+ */
1149
+ type AfterRollbackCallback = () => void | Promise<void>;
1150
+ /**
1151
+ * Serializes the savepoint frames opened directly off one transaction context
1152
+ *
1153
+ * @see createNestedFrameGate
1154
+ */
1155
+ type NestedFrameGate = {
1156
+ /** Run `frame` once every frame queued before it on this context has finished */
1157
+ run<T>(frame: () => Promise<T>): Promise<T>;
1158
+ };
1142
1159
  /**
1143
1160
  * Transaction context stored in AsyncLocalStorage
1144
1161
  */
@@ -1148,8 +1165,14 @@ type TransactionContext<TDatabase extends DrizzleDatabase = DrizzleDatabase> = {
1148
1165
  /** Unique transaction ID for logging and tracing */
1149
1166
  txId: string;
1150
1167
  level: number;
1168
+ /** Callbacks to execute before the root transaction commits (still inside it) */
1169
+ beforeCommitCallbacks: BeforeCommitCallback[];
1151
1170
  /** Callbacks to execute after root transaction commits */
1152
1171
  afterCommitCallbacks: AfterCommitCallback[];
1172
+ /** Callbacks to execute after the root transaction rolled back */
1173
+ afterRollbackCallbacks: AfterRollbackCallback[];
1174
+ /** Serializes the savepoint frames opened directly off THIS context */
1175
+ nestedFrames: NestedFrameGate;
1153
1176
  };
1154
1177
  /**
1155
1178
  * Get current transaction object and metadata from AsyncLocalStorage
@@ -1187,7 +1210,7 @@ callback: () => Promise<T>): Promise<T>;
1187
1210
  *
1188
1211
  * @example
1189
1212
  * ```typescript
1190
- * import { onAfterCommit } from '@spfn/core/db/transaction';
1213
+ * import { onAfterCommit } from '@spfn/core/db';
1191
1214
  *
1192
1215
  * async function submit(spaceId: string, chatId: string)
1193
1216
  * {
@@ -1201,6 +1224,77 @@ callback: () => Promise<T>): Promise<T>;
1201
1224
  * ```
1202
1225
  */
1203
1226
  declare function onAfterCommit(callback: AfterCommitCallback): void;
1227
+ /**
1228
+ * Register a callback to run just before the current transaction commits
1229
+ *
1230
+ * - Inside a transaction: queued and executed after the root callback resolves,
1231
+ * while the transaction is still open — the callback MAY run statements and
1232
+ * they are part of the same commit
1233
+ * - Outside a transaction: executed immediately with a WARNING (same rationale as
1234
+ * onAfterCommit — there is nothing left to commit), and the abort semantics
1235
+ * below do not apply: there is no transaction for a throw to roll back
1236
+ * - Nested transactions: callbacks bubble up to root transaction
1237
+ * - Callbacks run in registration order, inside the transaction context
1238
+ * (getTransaction() returns the live tx)
1239
+ * - The queue is snapshot before the pass, so a callback registered BY a
1240
+ * beforeCommit callback does not run for this commit — it would otherwise
1241
+ * grow the queue mid-iteration and loop forever inside the open transaction
1242
+ * - A throw ABORTS: later callbacks are skipped, the transaction rolls back,
1243
+ * the error propagates to the caller, and afterRollback callbacks fire
1244
+ *
1245
+ * @example
1246
+ * ```typescript
1247
+ * import { runInTransaction, onBeforeCommit } from '@spfn/core/db';
1248
+ *
1249
+ * async function transfer(fromId: string, toId: string, amount: number)
1250
+ * {
1251
+ * // The transaction is what gives the check teeth — registered outside one,
1252
+ * // the callback runs immediately and its throw aborts nothing.
1253
+ * await runInTransaction(async () =>
1254
+ * {
1255
+ * await accountRepo.debit(fromId, amount);
1256
+ * await accountRepo.credit(toId, amount);
1257
+ *
1258
+ * // Last-moment invariant check: a throw here rolls the whole transfer back.
1259
+ * onBeforeCommit(() => assertNoNegativeBalance(fromId));
1260
+ * });
1261
+ * }
1262
+ * ```
1263
+ */
1264
+ declare function onBeforeCommit(callback: BeforeCommitCallback): void;
1265
+ /**
1266
+ * Register a callback to run after the current transaction rolled back
1267
+ *
1268
+ * - Inside a transaction: queued and executed after the ROOT transaction rolled
1269
+ * back, before the causing error leaves runInTransaction / the middleware
1270
+ * - Outside a transaction: no-op with a warning — there is no rollback to wait for
1271
+ * - Nested transactions: callbacks bubble up to root transaction. A nested
1272
+ * rollback that the root survives does NOT fire them; these hooks are about
1273
+ * the root transaction's fate, not a savepoint's
1274
+ * - Callbacks run outside the transaction context (new connection for DB access)
1275
+ * - Errors are logged but never thrown: the original error keeps propagating
1276
+ * unchanged, never replaced by a callback failure
1277
+ *
1278
+ * @example
1279
+ * ```typescript
1280
+ * import { runInTransaction, onAfterRollback } from '@spfn/core/db';
1281
+ *
1282
+ * async function importAvatar(userId: string, file: Blob)
1283
+ * {
1284
+ * // Upload first: external I/O never belongs inside the transaction.
1285
+ * const key = await objectStore.put(file);
1286
+ *
1287
+ * await runInTransaction(async () =>
1288
+ * {
1289
+ * await userRepo.updateAvatar(userId, key);
1290
+ *
1291
+ * // The upload cannot roll back on its own — undo it if the write never lands.
1292
+ * onAfterRollback(() => objectStore.delete(key));
1293
+ * });
1294
+ * }
1295
+ * ```
1296
+ */
1297
+ declare function onAfterRollback(callback: AfterRollbackCallback): void;
1204
1298
 
1205
1299
  /**
1206
1300
  * Transaction middleware options
@@ -1245,6 +1339,21 @@ interface TransactionalOptions {
1245
1339
  * @default 30000 (30s) or TRANSACTION_IDLE_TIMEOUT environment variable
1246
1340
  */
1247
1341
  idleTimeout?: number;
1342
+ /**
1343
+ * Run in an independent transaction instead of joining an ambient one.
1344
+ *
1345
+ * Only bites when the middleware itself runs nested — a sub-app mounted
1346
+ * under a route that already applied `Transactional()`, or a handler invoked
1347
+ * from inside `runInTransaction`. By default that inner run takes a SAVEPOINT
1348
+ * on the outer transaction; `requiresNew: true` gives it a real `BEGIN` on a
1349
+ * second pooled connection, with its own timeouts and its own hook queues.
1350
+ *
1351
+ * See `RunInTransactionOptions.requiresNew` for the pool and self-deadlock
1352
+ * costs — they apply here unchanged.
1353
+ *
1354
+ * @default false
1355
+ */
1356
+ requiresNew?: boolean;
1248
1357
  }
1249
1358
  /**
1250
1359
  * Transaction middleware for Hono routes
@@ -1282,6 +1391,9 @@ interface TransactionalOptions {
1282
1391
  * - Success: Auto-commit
1283
1392
  * - Error: Auto-rollback
1284
1393
  * - Detects context.error to trigger rollback
1394
+ * - Hooks: this delegates to runInTransaction, so onBeforeCommit, onAfterCommit
1395
+ * and onAfterRollback behave exactly as they do there. afterRollback callbacks
1396
+ * have already run by the time the error reaches the conversion below.
1285
1397
  *
1286
1398
  * 📊 Transaction logging:
1287
1399
  * - Auto-logs transaction start/commit/rollback
@@ -1317,8 +1429,12 @@ interface RunInTransactionOptions {
1317
1429
  * - `timeout: undefined` - Uses default (30s or TRANSACTION_TIMEOUT env var)
1318
1430
  * - `timeout: N` - Sets timeout to N milliseconds (1 to 2147483647)
1319
1431
  *
1320
- * Note: Timeout is only applied to root transactions. Nested transactions
1321
- * (SAVEPOINTs) inherit the timeout from the outer transaction.
1432
+ * Note: Timeout is only applied to root transactions. A nested call takes a
1433
+ * SAVEPOINT on the outer transaction's connection, where the outer
1434
+ * transaction's `SET LOCAL statement_timeout` is already in force — so the
1435
+ * nested call genuinely inherits it, and its own `timeout` is ignored (a
1436
+ * warning is logged when the caller passed one explicitly). A
1437
+ * `requiresNew: true` call is a root and gets its own.
1322
1438
  *
1323
1439
  * @default 30000 (30 seconds) or TRANSACTION_TIMEOUT environment variable
1324
1440
  *
@@ -1355,6 +1471,48 @@ interface RunInTransactionOptions {
1355
1471
  * @default 'transaction'
1356
1472
  */
1357
1473
  context?: string;
1474
+ /**
1475
+ * Run in an independent transaction instead of joining an ambient one.
1476
+ *
1477
+ * By default a call made while another transaction is open takes a SAVEPOINT
1478
+ * on that transaction's connection: its writes commit or roll back with the
1479
+ * outer transaction. `requiresNew: true` opens a real `BEGIN` on a SECOND
1480
+ * pooled connection instead, so the work commits on its own and survives an
1481
+ * outer rollback — an audit trail or a failed-attempt record, for example.
1482
+ *
1483
+ * Being a root transaction, it gets its own `statement_timeout`,
1484
+ * `idle_in_transaction_session_timeout`, and its OWN hook queues:
1485
+ * `onBeforeCommit` / `onAfterCommit` / `onAfterRollback` registered inside it
1486
+ * fire on ITS outcome, not the outer transaction's.
1487
+ *
1488
+ * Two costs, both consequences of the second connection:
1489
+ * - It holds a second connection for its whole duration, so it counts twice
1490
+ * against the pool. Keep it short and don't fan it out.
1491
+ * - It cannot see the outer transaction's uncommitted writes, and it BLOCKS
1492
+ * on any row the outer transaction has locked. Since the outer transaction
1493
+ * is waiting for this call to return, that block is a self-deadlock that
1494
+ * only `statement_timeout` breaks. Never touch rows the outer transaction
1495
+ * wrote.
1496
+ *
1497
+ * @default false
1498
+ *
1499
+ * @example
1500
+ * ```typescript
1501
+ * await runInTransaction(async () =>
1502
+ * {
1503
+ * await orderRepo.create(order);
1504
+ *
1505
+ * // Lands even if the order below rolls the outer transaction back.
1506
+ * await runInTransaction(
1507
+ * () => auditRepo.record('order.attempted', order.id),
1508
+ * { requiresNew: true },
1509
+ * );
1510
+ *
1511
+ * await inventoryRepo.reserve(order.items); // may throw
1512
+ * });
1513
+ * ```
1514
+ */
1515
+ requiresNew?: boolean;
1358
1516
  }
1359
1517
  /**
1360
1518
  * Run a callback function within a database transaction
@@ -1366,6 +1524,15 @@ interface RunInTransactionOptions {
1366
1524
  * - Warns about slow transactions
1367
1525
  * - Enforces timeout if configured
1368
1526
  *
1527
+ * Called with a transaction already open on the async call chain, it takes a
1528
+ * SAVEPOINT on that transaction rather than opening an independent one: the work
1529
+ * runs on the same connection, sees the outer transaction's uncommitted writes,
1530
+ * and commits with it. A throw that the caller catches unwinds to the SAVEPOINT
1531
+ * and leaves the outer transaction healthy; a throw that propagates rolls the
1532
+ * whole thing back. Nested calls off one transaction are serialized — see
1533
+ * `openTransaction` — so `Promise.all` over them runs them one at a time. Pass
1534
+ * `requiresNew: true` for an independent transaction on its own connection.
1535
+ *
1369
1536
  * Errors are propagated to the caller without modification.
1370
1537
  * Caller is responsible for error handling and conversion.
1371
1538
  *
@@ -1680,11 +1847,11 @@ declare function count<T extends PgTable>(table: T, where?: WhereObject<InferSel
1680
1847
  *
1681
1848
  * @example With Transactions
1682
1849
  * ```typescript
1683
- * import { runWithTransaction } from '@spfn/core/db';
1850
+ * import { runInTransaction } from '@spfn/core/db';
1684
1851
  *
1685
1852
  * const userRepo = new UserRepository();
1686
1853
  *
1687
- * await runWithTransaction(async () => {
1854
+ * await runInTransaction(async () => {
1688
1855
  * // Both db and readDb automatically use the transaction context
1689
1856
  * const user = await userRepo.create({ name: 'John' });
1690
1857
  * await userRepo.findById(user.id); // Uses same transaction
@@ -2006,4 +2173,4 @@ declare abstract class BaseRepository<TRelations extends AnyRelations = EmptyRel
2006
2173
  protected _count<T extends PgTable>(table: T, where?: Record<string, any> | SQL | undefined): Promise<number>;
2007
2174
  }
2008
2175
 
2009
- export { type AfterCommitCallback, BaseRepository, type DatabaseClients, type DatabaseInitOptions, type DatabaseOptions, type DatabaseProvider, type DatabaseTransaction, type DefaultDatabase, type DrizzleConfigOptions, type DrizzleDatabase, type FunctionMigrationEntry, type FunctionMigrationInfo, type MigrationStatus, type MigrationStatusDb, type MigrationTargetStatus, PROJECT_MIGRATIONS_TABLE, PROJECT_TARGET_NAME, type PoolConfig, RUN_MIGRATIONS_HINT, type RepositoryDatabase, RepositoryError, type RetryConfig, type RunInTransactionOptions, type TransactionContext, type TransactionDB, Transactional, type TransactionalOptions, auditFields, checkConnection, closeDatabase, collectMigrationStatus, count, countPendingMigrations, create, createDatabaseConnection, createDatabaseFromEnv, createMany, createSchema, deleteMany, deleteOne, detectDialect, discoverFunctionMigrations, enumText, filterPendingEntries, findMany, findOne, forceReconnectDatabase, foreignKey, formatPendingMigrations, fromPostgresError, functionMigrationsTable, generateDrizzleConfigFile, getDatabase, getDatabaseInfo, getDrizzleConfig, getSchemaInfo, getTransaction, getTransactionContext, hasMigrationTargets, id, initDatabase, isConnectionLevelError, migrationTargets, onAfterCommit, optionalForeignKey, packageNameToSchema, pendingMigrationTargets, pendingMigrationsSummary, projectMigrationsDir, publishingFields, readMigrationEntries, reportDatabaseError, resetConnectionErrorCounter, runInTransaction, runWithTransaction, setDatabase, setDatabaseProvider, softDelete, timestamps, typedJsonb, updateMany, updateOne, upsert, utcTimestamp, uuid, verificationTimestamp };
2176
+ export { type AfterCommitCallback, type AfterRollbackCallback, BaseRepository, type BeforeCommitCallback, type DatabaseClients, type DatabaseInitOptions, type DatabaseOptions, type DatabaseProvider, type DatabaseTransaction, type DefaultDatabase, type DrizzleConfigOptions, type DrizzleDatabase, type FunctionMigrationEntry, type FunctionMigrationInfo, type MigrationStatus, type MigrationStatusDb, type MigrationTargetStatus, type NestedFrameGate, PROJECT_MIGRATIONS_TABLE, PROJECT_TARGET_NAME, type PoolConfig, RUN_MIGRATIONS_HINT, type RenderableDrizzleConfig, type RepositoryDatabase, RepositoryError, type RetryConfig, type RunInTransactionOptions, type TransactionContext, type TransactionDB, Transactional, type TransactionalOptions, auditFields, checkConnection, closeDatabase, collectMigrationStatus, count, countPendingMigrations, create, createDatabaseConnection, createDatabaseFromEnv, createMany, createSchema, deleteMany, deleteOne, detectDialect, discoverFunctionMigrations, enumText, filterPendingEntries, findMany, findOne, forceReconnectDatabase, foreignKey, formatPendingMigrations, fromPostgresError, functionMigrationsTable, generateDrizzleConfigFile, getDatabase, getDatabaseInfo, getDrizzleConfig, getSchemaInfo, getTransaction, getTransactionContext, hasMigrationTargets, id, initDatabase, isConnectionLevelError, migrationTargets, onAfterCommit, onAfterRollback, onBeforeCommit, optionalForeignKey, packageNameToSchema, pendingMigrationTargets, pendingMigrationsSummary, projectMigrationsDir, publishingFields, readMigrationEntries, renderDrizzleConfig, reportDatabaseError, resetConnectionErrorCounter, runInTransaction, runWithTransaction, setDatabase, setDatabaseProvider, softDelete, timestamps, typedJsonb, updateMany, updateOne, upsert, utcTimestamp, uuid, verificationTimestamp };