@fragno-dev/db 0.1.15 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +242 -179
- package/CHANGELOG.md +40 -0
- package/README.md +123 -8
- package/dist/adapters/adapters.d.ts +5 -5
- package/dist/adapters/adapters.d.ts.map +1 -1
- package/dist/adapters/adapters.js.map +1 -1
- package/dist/adapters/drizzle/drizzle-adapter.d.ts +6 -21
- package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
- package/dist/adapters/drizzle/drizzle-adapter.js +7 -54
- package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
- package/dist/adapters/drizzle/generate.d.ts +3 -0
- package/dist/adapters/drizzle/generate.d.ts.map +1 -1
- package/dist/adapters/drizzle/generate.js +36 -28
- package/dist/adapters/drizzle/generate.js.map +1 -1
- package/dist/adapters/generic-sql/driver-config.d.ts +74 -0
- package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -0
- package/dist/adapters/generic-sql/driver-config.js +94 -0
- package/dist/adapters/generic-sql/driver-config.js.map +1 -0
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +43 -0
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -0
- package/dist/adapters/generic-sql/generic-sql-adapter.js +87 -0
- package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -0
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js +67 -0
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -0
- package/dist/adapters/generic-sql/migration/cold-kysely.js +33 -0
- package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -0
- package/dist/adapters/generic-sql/migration/dialect/mysql.js +60 -0
- package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -0
- package/dist/adapters/generic-sql/migration/dialect/postgres.js +59 -0
- package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -0
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js +96 -0
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -0
- package/dist/adapters/generic-sql/migration/executor.d.ts +15 -0
- package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -0
- package/dist/adapters/generic-sql/migration/executor.js +18 -0
- package/dist/adapters/generic-sql/migration/executor.js.map +1 -0
- package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
- package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
- package/dist/adapters/generic-sql/migration/prepared-migrations.js +68 -0
- package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -0
- package/dist/adapters/generic-sql/migration/sql-generator.js +212 -0
- package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -0
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +32 -0
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -0
- package/dist/adapters/generic-sql/query/cursor-utils.js +37 -0
- package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -0
- package/dist/adapters/generic-sql/query/dialect/mysql.js +33 -0
- package/dist/adapters/generic-sql/query/dialect/mysql.js.map +1 -0
- package/dist/adapters/generic-sql/query/dialect/postgres.js +32 -0
- package/dist/adapters/generic-sql/query/dialect/postgres.js.map +1 -0
- package/dist/adapters/generic-sql/query/dialect/sqlite.js +32 -0
- package/dist/adapters/generic-sql/query/dialect/sqlite.js.map +1 -0
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +152 -0
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -0
- package/dist/adapters/generic-sql/query/select-builder.js +69 -0
- package/dist/adapters/generic-sql/query/select-builder.js.map +1 -0
- package/dist/adapters/generic-sql/query/sql-query-compiler.js +145 -0
- package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -0
- package/dist/adapters/generic-sql/query/where-builder.js +129 -0
- package/dist/adapters/generic-sql/query/where-builder.js.map +1 -0
- package/dist/adapters/generic-sql/result-interpreter.js +74 -0
- package/dist/adapters/generic-sql/result-interpreter.js.map +1 -0
- package/dist/adapters/generic-sql/uow-decoder.js +105 -0
- package/dist/adapters/generic-sql/uow-decoder.js.map +1 -0
- package/dist/adapters/generic-sql/uow-encoder.js +93 -0
- package/dist/adapters/generic-sql/uow-encoder.js.map +1 -0
- package/dist/adapters/kysely/kysely-adapter.d.ts +5 -18
- package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
- package/dist/adapters/kysely/kysely-adapter.js +6 -165
- package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
- package/dist/adapters/{drizzle/drizzle-query.js → shared/from-unit-of-work-compiler.js} +47 -61
- package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -0
- package/dist/adapters/{drizzle/shared.d.ts → shared/table-name-mapper.d.ts} +2 -4
- package/dist/adapters/shared/table-name-mapper.d.ts.map +1 -0
- package/dist/adapters/shared/table-name-mapper.js +43 -0
- package/dist/adapters/shared/table-name-mapper.js.map +1 -0
- package/dist/adapters/shared/uow-operation-compiler.js +105 -0
- package/dist/adapters/shared/uow-operation-compiler.js.map +1 -0
- package/dist/db-fragment-definition-builder.d.ts +107 -19
- package/dist/db-fragment-definition-builder.d.ts.map +1 -1
- package/dist/db-fragment-definition-builder.js +134 -20
- package/dist/db-fragment-definition-builder.js.map +1 -1
- package/dist/fragments/internal-fragment.d.ts +39 -5
- package/dist/fragments/internal-fragment.d.ts.map +1 -1
- package/dist/fragments/internal-fragment.js +82 -10
- package/dist/fragments/internal-fragment.js.map +1 -1
- package/dist/hooks/hooks.d.ts +51 -0
- package/dist/hooks/hooks.d.ts.map +1 -0
- package/dist/hooks/hooks.js +88 -0
- package/dist/hooks/hooks.js.map +1 -0
- package/dist/migration-engine/generation-engine.d.ts +0 -2
- package/dist/migration-engine/generation-engine.d.ts.map +1 -1
- package/dist/migration-engine/generation-engine.js +23 -61
- package/dist/migration-engine/generation-engine.js.map +1 -1
- package/dist/mod.d.ts +34 -10
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +47 -16
- package/dist/mod.js.map +1 -1
- package/dist/node_modules/.pnpm/{rou3@0.7.8 → rou3@0.7.10}/node_modules/rou3/dist/index.js +1 -1
- package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +1 -0
- package/dist/packages/fragno/dist/api/fragment-instantiator.js +69 -31
- package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -1
- package/dist/query/column-defaults.js +27 -0
- package/dist/query/column-defaults.js.map +1 -0
- package/dist/query/cursor.d.ts +4 -4
- package/dist/query/cursor.d.ts.map +1 -1
- package/dist/query/cursor.js +8 -6
- package/dist/query/cursor.js.map +1 -1
- package/dist/query/orm/orm.d.ts +1 -1
- package/dist/query/orm/orm.js.map +1 -1
- package/dist/query/serialize/create-sql-serializer.js +30 -0
- package/dist/query/serialize/create-sql-serializer.js.map +1 -0
- package/dist/query/serialize/dialect/mysql-serializer.js +87 -0
- package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -0
- package/dist/query/serialize/dialect/postgres-serializer.js +80 -0
- package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -0
- package/dist/query/serialize/dialect/sqlite-serializer.js +93 -0
- package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -0
- package/dist/query/serialize/sql-serializer.js +67 -0
- package/dist/query/serialize/sql-serializer.js.map +1 -0
- package/dist/query/{query.d.ts → simple-query-interface.d.ts} +5 -5
- package/dist/query/simple-query-interface.d.ts.map +1 -0
- package/dist/query/{execute-unit-of-work.d.ts → unit-of-work/execute-unit-of-work.d.ts} +50 -4
- package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
- package/dist/query/{execute-unit-of-work.js → unit-of-work/execute-unit-of-work.js} +150 -5
- package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -0
- package/dist/query/{retry-policy.d.ts → unit-of-work/retry-policy.d.ts} +1 -1
- package/dist/query/unit-of-work/retry-policy.d.ts.map +1 -0
- package/dist/query/{retry-policy.js → unit-of-work/retry-policy.js} +1 -1
- package/dist/query/unit-of-work/retry-policy.js.map +1 -0
- package/dist/query/{unit-of-work.d.ts → unit-of-work/unit-of-work.d.ts} +69 -21
- package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -0
- package/dist/query/{unit-of-work.js → unit-of-work/unit-of-work.js} +83 -22
- package/dist/query/unit-of-work/unit-of-work.js.map +1 -0
- package/dist/query/value-decoding.js +71 -0
- package/dist/query/value-decoding.js.map +1 -0
- package/dist/query/value-encoding.js +124 -0
- package/dist/query/value-encoding.js.map +1 -0
- package/dist/schema/type-conversion/create-sql-type-mapper.js +29 -0
- package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -0
- package/dist/schema/type-conversion/dialect/mysql.js +57 -0
- package/dist/schema/type-conversion/dialect/mysql.js.map +1 -0
- package/dist/schema/type-conversion/dialect/postgres.js +56 -0
- package/dist/schema/type-conversion/dialect/postgres.js.map +1 -0
- package/dist/schema/type-conversion/dialect/sqlite.js +52 -0
- package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -0
- package/dist/schema/type-conversion/type-mapping.js +63 -0
- package/dist/schema/type-conversion/type-mapping.js.map +1 -0
- package/dist/sql-driver/connection/connection-provider.d.ts +13 -0
- package/dist/sql-driver/connection/connection-provider.d.ts.map +1 -0
- package/dist/sql-driver/connection/connection-provider.js +19 -0
- package/dist/sql-driver/connection/connection-provider.js.map +1 -0
- package/dist/sql-driver/connection/single-connection-provider.js +23 -0
- package/dist/sql-driver/connection/single-connection-provider.js.map +1 -0
- package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
- package/dist/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
- package/dist/sql-driver/dialects/dialects.d.ts +2 -0
- package/dist/sql-driver/dialects/dialects.js +3 -0
- package/dist/sql-driver/dialects/durable-object-dialect.d.ts +72 -0
- package/dist/sql-driver/dialects/durable-object-dialect.d.ts.map +1 -0
- package/dist/sql-driver/dialects/durable-object-dialect.js +130 -0
- package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -0
- package/dist/sql-driver/driver/runtime-driver.d.ts +23 -0
- package/dist/sql-driver/driver/runtime-driver.d.ts.map +1 -0
- package/dist/sql-driver/driver/runtime-driver.js +56 -0
- package/dist/sql-driver/driver/runtime-driver.js.map +1 -0
- package/dist/sql-driver/query-executor/default-query-executor.js +26 -0
- package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -0
- package/dist/sql-driver/query-executor/plugin.d.ts +17 -0
- package/dist/sql-driver/query-executor/plugin.d.ts.map +1 -0
- package/dist/sql-driver/query-executor/query-executor-base.js +25 -0
- package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -0
- package/dist/sql-driver/query-executor/query-executor.d.ts +36 -0
- package/dist/sql-driver/query-executor/query-executor.d.ts.map +1 -0
- package/dist/sql-driver/sql-driver-adapter.d.ts +29 -0
- package/dist/sql-driver/sql-driver-adapter.d.ts.map +1 -0
- package/dist/sql-driver/sql-driver-adapter.js +68 -0
- package/dist/sql-driver/sql-driver-adapter.js.map +1 -0
- package/dist/sql-driver/sql-driver.d.ts +38 -0
- package/dist/sql-driver/sql-driver.d.ts.map +1 -0
- package/dist/sql-driver/sql-driver.js +1 -0
- package/dist/sql-driver/sql.js +50 -0
- package/dist/sql-driver/sql.js.map +1 -0
- package/dist/with-database.d.ts +6 -2
- package/dist/with-database.d.ts.map +1 -1
- package/dist/with-database.js +1 -1
- package/dist/with-database.js.map +1 -1
- package/package.json +39 -12
- package/src/adapters/adapters.ts +8 -5
- package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +61 -169
- package/src/adapters/drizzle/{drizzle-adapter-sqlite.test.ts → drizzle-adapter-sqlite3.test.ts} +31 -55
- package/src/adapters/drizzle/drizzle-adapter.ts +15 -107
- package/src/adapters/drizzle/generate.test.ts +2 -2
- package/src/adapters/drizzle/generate.ts +78 -34
- package/src/adapters/drizzle/migrate-drizzle.test.ts +19 -0
- package/src/adapters/drizzle/shared.ts +0 -34
- package/src/adapters/drizzle/test-utils.ts +3 -3
- package/src/adapters/generic-sql/README.md +14 -0
- package/src/adapters/generic-sql/driver-config.ts +144 -0
- package/src/adapters/generic-sql/generic-sql-adapter.test.ts +50 -0
- package/src/adapters/generic-sql/generic-sql-adapter.ts +146 -0
- package/src/adapters/generic-sql/generic-sql-uow-executor.ts +130 -0
- package/src/adapters/generic-sql/migration/cold-kysely.ts +55 -0
- package/src/adapters/{kysely/migration/execute-mysql.test.ts → generic-sql/migration/dialect/mysql.test.ts} +342 -484
- package/src/adapters/generic-sql/migration/dialect/mysql.ts +104 -0
- package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +1008 -0
- package/src/adapters/generic-sql/migration/dialect/postgres.ts +113 -0
- package/src/adapters/{kysely/migration/execute-sqlite.test.ts → generic-sql/migration/dialect/sqlite.test.ts} +307 -510
- package/src/adapters/generic-sql/migration/dialect/sqlite.ts +189 -0
- package/src/adapters/generic-sql/migration/executor.ts +33 -0
- package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +661 -0
- package/src/adapters/generic-sql/migration/prepared-migrations.ts +214 -0
- package/src/adapters/generic-sql/migration/sql-generator.ts +413 -0
- package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +36 -0
- package/src/adapters/generic-sql/query/cursor-utils.ts +56 -0
- package/src/adapters/generic-sql/query/dialect/mysql.ts +34 -0
- package/src/adapters/generic-sql/query/dialect/postgres.ts +32 -0
- package/src/adapters/generic-sql/query/dialect/sqlite.ts +32 -0
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +1568 -0
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +314 -0
- package/src/adapters/generic-sql/query/select-builder.test.ts +256 -0
- package/src/adapters/generic-sql/query/select-builder.ts +137 -0
- package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +195 -0
- package/src/adapters/generic-sql/query/sql-query-compiler.ts +367 -0
- package/src/adapters/generic-sql/query/where-builder.test.ts +744 -0
- package/src/adapters/generic-sql/query/where-builder.ts +211 -0
- package/src/adapters/generic-sql/result-interpreter.ts +102 -0
- package/src/adapters/generic-sql/test/generic-drizzle-adapter-sqlite3.test.ts +899 -0
- package/src/adapters/generic-sql/uow-decoder.test.ts +399 -0
- package/src/adapters/generic-sql/uow-decoder.ts +152 -0
- package/src/adapters/generic-sql/uow-encoder.test.ts +183 -0
- package/src/adapters/generic-sql/uow-encoder.ts +131 -0
- package/src/adapters/kysely/kysely-adapter-pglite.test.ts +26 -76
- package/src/adapters/kysely/{kysely-adapter-sqlite.test.ts → kysely-adapter-sqlocal.test.ts} +76 -17
- package/src/adapters/kysely/kysely-adapter.ts +10 -250
- package/src/adapters/{drizzle/drizzle-query.ts → shared/from-unit-of-work-compiler.ts} +110 -104
- package/src/adapters/shared/table-name-mapper.ts +50 -0
- package/src/adapters/shared/uow-operation-compiler.ts +211 -0
- package/src/db-fragment-definition-builder.test.ts +2 -2
- package/src/db-fragment-definition-builder.ts +461 -50
- package/src/db-fragment-instantiator.test.ts +78 -2
- package/src/db-fragment-integration.test.ts +14 -16
- package/src/fragments/internal-fragment.test.ts +434 -45
- package/src/fragments/internal-fragment.ts +183 -20
- package/src/hooks/hooks.test.ts +587 -0
- package/src/hooks/hooks.ts +179 -0
- package/src/migration-engine/generation-engine.test.ts +44 -54
- package/src/migration-engine/generation-engine.ts +48 -94
- package/src/mod.ts +117 -29
- package/src/query/column-defaults.ts +49 -0
- package/src/query/cursor.test.ts +31 -6
- package/src/query/cursor.ts +11 -7
- package/src/query/orm/orm.ts +1 -1
- package/src/query/query-type.test.ts +9 -9
- package/src/query/serialize/create-sql-serializer.ts +34 -0
- package/src/query/serialize/dialect/mysql-serializer.ts +142 -0
- package/src/query/serialize/dialect/postgres-serializer.ts +129 -0
- package/src/query/serialize/dialect/sqlite-serializer.test.ts +251 -0
- package/src/query/serialize/dialect/sqlite-serializer.ts +156 -0
- package/src/query/serialize/sql-serializer.ts +143 -0
- package/src/query/{query.ts → simple-query-interface.ts} +2 -2
- package/src/query/{execute-unit-of-work.test.ts → unit-of-work/execute-unit-of-work.test.ts} +571 -17
- package/src/query/{execute-unit-of-work.ts → unit-of-work/execute-unit-of-work.ts} +361 -12
- package/src/query/{unit-of-work-coordinator.test.ts → unit-of-work/unit-of-work-coordinator.test.ts} +290 -44
- package/src/query/{unit-of-work-types.test.ts → unit-of-work/unit-of-work-types.test.ts} +5 -3
- package/src/query/{unit-of-work.test.ts → unit-of-work/unit-of-work.test.ts} +100 -9
- package/src/query/{unit-of-work.ts → unit-of-work/unit-of-work.ts} +174 -49
- package/src/query/{result-transform.test.ts → value-decoding.test.ts} +45 -427
- package/src/query/value-decoding.ts +113 -0
- package/src/query/value-encoding.test.ts +390 -0
- package/src/query/value-encoding.ts +168 -0
- package/src/schema/create.test.ts +5 -1
- package/src/schema/serialize.test.ts +165 -407
- package/src/schema/type-conversion/create-sql-type-mapper.ts +28 -0
- package/src/schema/type-conversion/dialect/mysql.ts +64 -0
- package/src/schema/type-conversion/dialect/postgres.ts +62 -0
- package/src/schema/type-conversion/dialect/sqlite.ts +63 -0
- package/src/schema/type-conversion/type-mapping.test.ts +137 -0
- package/src/schema/type-conversion/type-mapping.ts +153 -0
- package/src/shared/connection-pool.ts +5 -5
- package/src/sql-driver/better-sqlite3.test.ts +126 -0
- package/src/sql-driver/connection/connection-provider.ts +27 -0
- package/src/sql-driver/connection/single-connection-provider.ts +42 -0
- package/src/sql-driver/dialect-adapter/dialect-adapter.ts +9 -0
- package/src/sql-driver/dialect-adapter/sqlite-dialect-adapter.ts +7 -0
- package/src/sql-driver/dialects/dialects.ts +1 -0
- package/src/sql-driver/dialects/durable-object-dialect.ts +260 -0
- package/src/sql-driver/driver/runtime-driver.ts +91 -0
- package/src/sql-driver/query-executor/default-query-executor.ts +38 -0
- package/src/sql-driver/query-executor/plugin.ts +22 -0
- package/src/sql-driver/query-executor/query-executor-base.ts +53 -0
- package/src/sql-driver/query-executor/query-executor.ts +44 -0
- package/src/sql-driver/sql-driver-adapter.ts +96 -0
- package/src/sql-driver/sql-driver.ts +53 -0
- package/src/sql-driver/sql.ts +57 -0
- package/src/sql-driver/sqlocal.test.ts +117 -0
- package/src/with-database.ts +35 -23
- package/tsdown.config.ts +7 -2
- package/dist/adapters/drizzle/drizzle-connection-pool.js +0 -40
- package/dist/adapters/drizzle/drizzle-connection-pool.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-query.d.ts +0 -23
- package/dist/adapters/drizzle/drizzle-query.d.ts.map +0 -1
- package/dist/adapters/drizzle/drizzle-query.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts +0 -10
- package/dist/adapters/drizzle/drizzle-uow-compiler.d.ts.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-compiler.js +0 -334
- package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-decoder.js +0 -123
- package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +0 -1
- package/dist/adapters/drizzle/drizzle-uow-executor.js +0 -160
- package/dist/adapters/drizzle/drizzle-uow-executor.js.map +0 -1
- package/dist/adapters/drizzle/join-column-utils.js +0 -28
- package/dist/adapters/drizzle/join-column-utils.js.map +0 -1
- package/dist/adapters/drizzle/shared.d.ts.map +0 -1
- package/dist/adapters/drizzle/shared.js +0 -35
- package/dist/adapters/drizzle/shared.js.map +0 -1
- package/dist/adapters/kysely/kysely-connection-pool.js +0 -41
- package/dist/adapters/kysely/kysely-connection-pool.js.map +0 -1
- package/dist/adapters/kysely/kysely-query-builder.js +0 -321
- package/dist/adapters/kysely/kysely-query-builder.js.map +0 -1
- package/dist/adapters/kysely/kysely-query-compiler.js +0 -67
- package/dist/adapters/kysely/kysely-query-compiler.js.map +0 -1
- package/dist/adapters/kysely/kysely-query.d.ts +0 -23
- package/dist/adapters/kysely/kysely-query.d.ts.map +0 -1
- package/dist/adapters/kysely/kysely-query.js +0 -230
- package/dist/adapters/kysely/kysely-query.js.map +0 -1
- package/dist/adapters/kysely/kysely-shared.d.ts +0 -14
- package/dist/adapters/kysely/kysely-shared.d.ts.map +0 -1
- package/dist/adapters/kysely/kysely-shared.js +0 -33
- package/dist/adapters/kysely/kysely-shared.js.map +0 -1
- package/dist/adapters/kysely/kysely-uow-compiler.js +0 -193
- package/dist/adapters/kysely/kysely-uow-compiler.js.map +0 -1
- package/dist/adapters/kysely/kysely-uow-executor.js +0 -93
- package/dist/adapters/kysely/kysely-uow-executor.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-base.js +0 -128
- package/dist/adapters/kysely/migration/execute-base.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-factory.js +0 -34
- package/dist/adapters/kysely/migration/execute-factory.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-mssql.js +0 -112
- package/dist/adapters/kysely/migration/execute-mssql.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-mysql.js +0 -93
- package/dist/adapters/kysely/migration/execute-mysql.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-postgres.js +0 -104
- package/dist/adapters/kysely/migration/execute-postgres.js.map +0 -1
- package/dist/adapters/kysely/migration/execute-sqlite.js +0 -123
- package/dist/adapters/kysely/migration/execute-sqlite.js.map +0 -1
- package/dist/adapters/kysely/migration/execute.js +0 -34
- package/dist/adapters/kysely/migration/execute.js.map +0 -1
- package/dist/migration-engine/create.d.ts +0 -37
- package/dist/migration-engine/create.d.ts.map +0 -1
- package/dist/migration-engine/create.js +0 -58
- package/dist/migration-engine/create.js.map +0 -1
- package/dist/migration-engine/shared.d.ts +0 -112
- package/dist/migration-engine/shared.d.ts.map +0 -1
- package/dist/node_modules/.pnpm/rou3@0.7.8/node_modules/rou3/dist/index.js.map +0 -1
- package/dist/query/execute-unit-of-work.d.ts.map +0 -1
- package/dist/query/execute-unit-of-work.js.map +0 -1
- package/dist/query/query.d.ts.map +0 -1
- package/dist/query/result-transform.js +0 -170
- package/dist/query/result-transform.js.map +0 -1
- package/dist/query/retry-policy.d.ts.map +0 -1
- package/dist/query/retry-policy.js.map +0 -1
- package/dist/query/unit-of-work.d.ts.map +0 -1
- package/dist/query/unit-of-work.js.map +0 -1
- package/dist/schema/serialize.js +0 -111
- package/dist/schema/serialize.js.map +0 -1
- package/src/adapters/drizzle/drizzle-adapter.test.ts +0 -122
- package/src/adapters/drizzle/drizzle-connection-pool.ts +0 -66
- package/src/adapters/drizzle/drizzle-query.test.ts +0 -499
- package/src/adapters/drizzle/drizzle-uow-compiler-mysql.test.ts +0 -1442
- package/src/adapters/drizzle/drizzle-uow-compiler-sqlite.test.ts +0 -1414
- package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +0 -1400
- package/src/adapters/drizzle/drizzle-uow-compiler.ts +0 -677
- package/src/adapters/drizzle/drizzle-uow-decoder.ts +0 -228
- package/src/adapters/drizzle/drizzle-uow-executor.ts +0 -309
- package/src/adapters/drizzle/join-column-utils.test.ts +0 -79
- package/src/adapters/drizzle/join-column-utils.ts +0 -39
- package/src/adapters/kysely/kysely-connection-pool.ts +0 -70
- package/src/adapters/kysely/kysely-query-builder.test.ts +0 -1344
- package/src/adapters/kysely/kysely-query-builder.ts +0 -666
- package/src/adapters/kysely/kysely-query-compiler.ts +0 -127
- package/src/adapters/kysely/kysely-query.test.ts +0 -498
- package/src/adapters/kysely/kysely-query.ts +0 -399
- package/src/adapters/kysely/kysely-shared.ts +0 -57
- package/src/adapters/kysely/kysely-uow-compiler.test.ts +0 -986
- package/src/adapters/kysely/kysely-uow-compiler.ts +0 -350
- package/src/adapters/kysely/kysely-uow-executor.ts +0 -164
- package/src/adapters/kysely/kysely-uow-joins.test.ts +0 -794
- package/src/adapters/kysely/migration/execute-base.ts +0 -256
- package/src/adapters/kysely/migration/execute-factory.ts +0 -53
- package/src/adapters/kysely/migration/execute-mssql.ts +0 -250
- package/src/adapters/kysely/migration/execute-mysql.ts +0 -211
- package/src/adapters/kysely/migration/execute-postgres.test.ts +0 -2657
- package/src/adapters/kysely/migration/execute-postgres.ts +0 -234
- package/src/adapters/kysely/migration/execute-sqlite.ts +0 -247
- package/src/adapters/kysely/migration/execute.ts +0 -50
- package/src/adapters/kysely/migration/kysely-migrator.test.ts +0 -261
- package/src/query/result-transform.ts +0 -274
- package/src/schema/serialize.ts +0 -407
- /package/dist/query/{query.js → simple-query-interface.js} +0 -0
- /package/src/query/{retry-policy.test.ts → unit-of-work/retry-policy.test.ts} +0 -0
- /package/src/query/{retry-policy.ts → unit-of-work/retry-policy.ts} +0 -0
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import type { AnySchema } from "./schema/create";
|
|
2
|
-
import type {
|
|
2
|
+
import type { SimpleQueryInterface } from "./query/simple-query-interface";
|
|
3
3
|
import type { DatabaseAdapter } from "./adapters/adapters";
|
|
4
|
-
import type { IUnitOfWork } from "./query/unit-of-work";
|
|
5
|
-
import { TypedUnitOfWork, UnitOfWork } from "./query/unit-of-work";
|
|
6
|
-
import type {
|
|
4
|
+
import type { IUnitOfWork } from "./query/unit-of-work/unit-of-work";
|
|
5
|
+
import { TypedUnitOfWork, UnitOfWork } from "./query/unit-of-work/unit-of-work";
|
|
6
|
+
import type {
|
|
7
|
+
RequestThisContext,
|
|
8
|
+
FragnoPublicConfig,
|
|
9
|
+
AnyFragnoInstantiatedFragment,
|
|
10
|
+
} from "@fragno-dev/core";
|
|
7
11
|
import {
|
|
8
12
|
FragmentDefinitionBuilder,
|
|
9
13
|
type FragmentDefinition,
|
|
@@ -11,9 +15,22 @@ import {
|
|
|
11
15
|
} from "@fragno-dev/core";
|
|
12
16
|
import {
|
|
13
17
|
executeRestrictedUnitOfWork,
|
|
18
|
+
executeTxArray,
|
|
19
|
+
executeTxCallbacks,
|
|
20
|
+
executeServiceTx,
|
|
14
21
|
type AwaitedPromisesInObject,
|
|
15
22
|
type ExecuteRestrictedUnitOfWorkOptions,
|
|
16
|
-
|
|
23
|
+
type HandlerTxCallbacks,
|
|
24
|
+
type ServiceTxCallbacks,
|
|
25
|
+
} from "./query/unit-of-work/execute-unit-of-work";
|
|
26
|
+
import {
|
|
27
|
+
prepareHookMutations,
|
|
28
|
+
processHooks,
|
|
29
|
+
type HooksMap,
|
|
30
|
+
type HookFn,
|
|
31
|
+
type HookContext,
|
|
32
|
+
} from "./hooks/hooks";
|
|
33
|
+
import type { InternalFragmentInstance } from "./fragments/internal-fragment";
|
|
17
34
|
|
|
18
35
|
/**
|
|
19
36
|
* Extended FragnoPublicConfig that includes a database adapter.
|
|
@@ -32,7 +49,7 @@ export type ImplicitDatabaseDependencies<TSchema extends AnySchema> = {
|
|
|
32
49
|
/**
|
|
33
50
|
* Database query engine for the fragment's schema.
|
|
34
51
|
*/
|
|
35
|
-
db:
|
|
52
|
+
db: SimpleQueryInterface<TSchema>;
|
|
36
53
|
/**
|
|
37
54
|
* The schema definition for this fragment.
|
|
38
55
|
*/
|
|
@@ -50,19 +67,43 @@ export type ImplicitDatabaseDependencies<TSchema extends AnySchema> = {
|
|
|
50
67
|
/**
|
|
51
68
|
* Service context for database fragments - provides restricted UOW access without execute methods.
|
|
52
69
|
*/
|
|
53
|
-
export type DatabaseServiceContext = RequestThisContext & {
|
|
70
|
+
export type DatabaseServiceContext<THooks extends HooksMap> = RequestThisContext & {
|
|
54
71
|
/**
|
|
55
72
|
* Get a typed, restricted Unit of Work for the given schema.
|
|
56
73
|
* @param schema - Schema to get a typed view for
|
|
57
74
|
* @returns TypedUnitOfWork (restricted version without execute methods)
|
|
58
75
|
*/
|
|
59
|
-
uow<TSchema extends AnySchema>(schema: TSchema): TypedUnitOfWork<TSchema, [], unknown>;
|
|
76
|
+
uow<TSchema extends AnySchema>(schema: TSchema): TypedUnitOfWork<TSchema, [], unknown, THooks>;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Execute a transaction with two-phase callbacks (retrieve + mutate).
|
|
80
|
+
*
|
|
81
|
+
* @param schema - Schema to use for the transaction
|
|
82
|
+
* @param callbacks - Object containing retrieve and mutate callbacks
|
|
83
|
+
* @returns Promise resolving to the mutation result with promises awaited 1 level deep
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* return this.tx(schema, {
|
|
88
|
+
* retrieve: (uow) => uow.findFirst("users", ...),
|
|
89
|
+
* mutate: async (uow, [user]) => {
|
|
90
|
+
* await validateUser(user);
|
|
91
|
+
* uow.update("users", user.id, ...).check();
|
|
92
|
+
* return { ok: true };
|
|
93
|
+
* }
|
|
94
|
+
* });
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
tx<TSchema extends AnySchema, TRetrievalResults extends unknown[], TMutationResult = void>(
|
|
98
|
+
schema: TSchema,
|
|
99
|
+
callbacks: ServiceTxCallbacks<TSchema, TRetrievalResults, TMutationResult, THooks>,
|
|
100
|
+
): Promise<AwaitedPromisesInObject<TMutationResult>>;
|
|
60
101
|
};
|
|
61
102
|
|
|
62
103
|
/**
|
|
63
104
|
* Handler context for database fragments - provides UOW execution with automatic retry support.
|
|
64
105
|
*/
|
|
65
|
-
export type DatabaseHandlerContext = RequestThisContext & {
|
|
106
|
+
export type DatabaseHandlerContext<THooks extends HooksMap = {}> = RequestThisContext & {
|
|
66
107
|
/**
|
|
67
108
|
* Execute a Unit of Work with explicit phase control and automatic retry support.
|
|
68
109
|
* This method provides an API where users call forSchema to create a schema-specific
|
|
@@ -96,7 +137,10 @@ export type DatabaseHandlerContext = RequestThisContext & {
|
|
|
96
137
|
*/
|
|
97
138
|
uow<TResult>(
|
|
98
139
|
callback: (context: {
|
|
99
|
-
forSchema: <
|
|
140
|
+
forSchema: <TSchema extends AnySchema, H extends HooksMap = THooks>(
|
|
141
|
+
schema: TSchema,
|
|
142
|
+
hooks?: H,
|
|
143
|
+
) => TypedUnitOfWork<TSchema, [], unknown, H>;
|
|
100
144
|
executeRetrieve: () => Promise<void>;
|
|
101
145
|
executeMutate: () => Promise<void>;
|
|
102
146
|
nonce: string;
|
|
@@ -104,6 +148,49 @@ export type DatabaseHandlerContext = RequestThisContext & {
|
|
|
104
148
|
}) => Promise<TResult> | TResult,
|
|
105
149
|
options?: Omit<ExecuteRestrictedUnitOfWorkOptions, "createUnitOfWork">,
|
|
106
150
|
): Promise<AwaitedPromisesInObject<TResult>>;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Execute a transaction with automatic retry support.
|
|
154
|
+
* Provides two overloads: array syntax (common case) and callback syntax (advanced).
|
|
155
|
+
*
|
|
156
|
+
* Array syntax - pass a factory function that returns service calls:
|
|
157
|
+
* ```ts
|
|
158
|
+
* const [transfer, notify] = await this.tx(
|
|
159
|
+
* () => [
|
|
160
|
+
* services.transfer({ from, to, amount }),
|
|
161
|
+
* services.notify({ userId, message })
|
|
162
|
+
* ]
|
|
163
|
+
* );
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* Callback syntax - for handlers that need direct UOW access:
|
|
167
|
+
* ```ts
|
|
168
|
+
* const result = await this.tx({
|
|
169
|
+
* retrieve: ({ forSchema }) => {
|
|
170
|
+
* const uow = forSchema(schema);
|
|
171
|
+
* uow.find("users", ...);
|
|
172
|
+
* return services.transfer({ ... });
|
|
173
|
+
* },
|
|
174
|
+
* mutate: ({ forSchema }, transferPromise) => {
|
|
175
|
+
* const uow = forSchema(schema);
|
|
176
|
+
* uow.create("auditLog", { ... });
|
|
177
|
+
* return transferPromise;
|
|
178
|
+
* }
|
|
179
|
+
* });
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* Note: Handler callbacks are synchronous only to prevent accidentally awaiting services in wrong place.
|
|
183
|
+
*/
|
|
184
|
+
// Overload 1: Array syntax (common case) - accepts a factory
|
|
185
|
+
tx<T extends readonly unknown[]>(
|
|
186
|
+
servicesFactory: () => readonly [...{ [K in keyof T]: Promise<T[K]> }],
|
|
187
|
+
options?: Omit<ExecuteRestrictedUnitOfWorkOptions, "createUnitOfWork">,
|
|
188
|
+
): Promise<{ [K in keyof T]: T[K] }>;
|
|
189
|
+
// Overload 2: Callback syntax (advanced, sync callbacks only)
|
|
190
|
+
tx<TRetrieveResult, TMutationResult>(
|
|
191
|
+
callbacks: HandlerTxCallbacks<TRetrieveResult, TMutationResult, THooks>,
|
|
192
|
+
options?: Omit<ExecuteRestrictedUnitOfWorkOptions, "createUnitOfWork">,
|
|
193
|
+
): Promise<AwaitedPromisesInObject<TMutationResult>>;
|
|
107
194
|
};
|
|
108
195
|
|
|
109
196
|
/**
|
|
@@ -117,7 +204,7 @@ export type DatabaseFragmentContext<TSchema extends AnySchema> = {
|
|
|
117
204
|
/**
|
|
118
205
|
* ORM query engine for the fragment's schema.
|
|
119
206
|
*/
|
|
120
|
-
db:
|
|
207
|
+
db: SimpleQueryInterface<TSchema>;
|
|
121
208
|
};
|
|
122
209
|
|
|
123
210
|
/**
|
|
@@ -163,8 +250,10 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
163
250
|
TServices,
|
|
164
251
|
TServiceDependencies,
|
|
165
252
|
TPrivateServices,
|
|
253
|
+
THooks extends HooksMap = {},
|
|
166
254
|
TServiceThisContext extends RequestThisContext = DatabaseHandlerContext,
|
|
167
255
|
THandlerThisContext extends RequestThisContext = DatabaseHandlerContext,
|
|
256
|
+
TLinkedFragments extends Record<string, AnyFragnoInstantiatedFragment> = {},
|
|
168
257
|
> {
|
|
169
258
|
// Store the base builder - we'll replace its storage and context setup when building
|
|
170
259
|
#baseBuilder: FragmentDefinitionBuilder<
|
|
@@ -177,10 +266,12 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
177
266
|
TPrivateServices,
|
|
178
267
|
TServiceThisContext,
|
|
179
268
|
THandlerThisContext,
|
|
180
|
-
DatabaseRequestStorage
|
|
269
|
+
DatabaseRequestStorage,
|
|
270
|
+
TLinkedFragments
|
|
181
271
|
>;
|
|
182
272
|
#schema: TSchema;
|
|
183
273
|
#namespace: string;
|
|
274
|
+
#hooksFactory?: (context: { config: TConfig; options: FragnoPublicConfigWithDatabase }) => THooks;
|
|
184
275
|
|
|
185
276
|
constructor(
|
|
186
277
|
baseBuilder: FragmentDefinitionBuilder<
|
|
@@ -193,14 +284,20 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
193
284
|
TPrivateServices,
|
|
194
285
|
TServiceThisContext,
|
|
195
286
|
THandlerThisContext,
|
|
196
|
-
DatabaseRequestStorage
|
|
287
|
+
DatabaseRequestStorage,
|
|
288
|
+
TLinkedFragments
|
|
197
289
|
>,
|
|
198
290
|
schema: TSchema,
|
|
199
291
|
namespace?: string,
|
|
292
|
+
hooksFactory?: (context: {
|
|
293
|
+
config: TConfig;
|
|
294
|
+
options: FragnoPublicConfigWithDatabase;
|
|
295
|
+
}) => THooks,
|
|
200
296
|
) {
|
|
201
297
|
this.#baseBuilder = baseBuilder;
|
|
202
298
|
this.#schema = schema;
|
|
203
|
-
this.#namespace = namespace ?? baseBuilder.name
|
|
299
|
+
this.#namespace = namespace ?? baseBuilder.name;
|
|
300
|
+
this.#hooksFactory = hooksFactory;
|
|
204
301
|
}
|
|
205
302
|
|
|
206
303
|
/**
|
|
@@ -211,7 +308,7 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
211
308
|
fn: (context: {
|
|
212
309
|
config: TConfig;
|
|
213
310
|
options: FragnoPublicConfigWithDatabase;
|
|
214
|
-
db:
|
|
311
|
+
db: SimpleQueryInterface<TSchema>;
|
|
215
312
|
databaseAdapter: DatabaseAdapter<any>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
216
313
|
}) => TNewDeps,
|
|
217
314
|
): DatabaseFragmentDefinitionBuilder<
|
|
@@ -222,8 +319,10 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
222
319
|
{},
|
|
223
320
|
TServiceDependencies,
|
|
224
321
|
{},
|
|
322
|
+
THooks,
|
|
225
323
|
TServiceThisContext,
|
|
226
|
-
THandlerThisContext
|
|
324
|
+
THandlerThisContext,
|
|
325
|
+
TLinkedFragments
|
|
227
326
|
> {
|
|
228
327
|
// Wrap user function to inject DB context
|
|
229
328
|
const wrappedFn = (context: { config: TConfig; options: FragnoPublicConfigWithDatabase }) => {
|
|
@@ -255,8 +354,12 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
255
354
|
// Create new base builder with wrapped function
|
|
256
355
|
const newBaseBuilder = this.#baseBuilder.withDependencies(wrappedFn);
|
|
257
356
|
|
|
258
|
-
|
|
259
|
-
|
|
357
|
+
return new DatabaseFragmentDefinitionBuilder(
|
|
358
|
+
newBaseBuilder,
|
|
359
|
+
this.#schema,
|
|
360
|
+
this.#namespace,
|
|
361
|
+
this.#hooksFactory,
|
|
362
|
+
);
|
|
260
363
|
}
|
|
261
364
|
|
|
262
365
|
providesBaseService<TNewService>(
|
|
@@ -277,12 +380,19 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
277
380
|
TServices,
|
|
278
381
|
TServiceDependencies,
|
|
279
382
|
TPrivateServices,
|
|
383
|
+
THooks,
|
|
280
384
|
TServiceThisContext,
|
|
281
|
-
THandlerThisContext
|
|
385
|
+
THandlerThisContext,
|
|
386
|
+
TLinkedFragments
|
|
282
387
|
> {
|
|
283
388
|
const newBaseBuilder = this.#baseBuilder.providesBaseService<TNewService>(fn);
|
|
284
389
|
|
|
285
|
-
return new DatabaseFragmentDefinitionBuilder(
|
|
390
|
+
return new DatabaseFragmentDefinitionBuilder(
|
|
391
|
+
newBaseBuilder,
|
|
392
|
+
this.#schema,
|
|
393
|
+
this.#namespace,
|
|
394
|
+
this.#hooksFactory,
|
|
395
|
+
);
|
|
286
396
|
}
|
|
287
397
|
|
|
288
398
|
providesService<TServiceName extends string, TService>(
|
|
@@ -304,15 +414,147 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
304
414
|
TServices & { [K in TServiceName]: TService },
|
|
305
415
|
TServiceDependencies,
|
|
306
416
|
TPrivateServices,
|
|
417
|
+
THooks,
|
|
307
418
|
TServiceThisContext,
|
|
308
|
-
THandlerThisContext
|
|
419
|
+
THandlerThisContext,
|
|
420
|
+
TLinkedFragments
|
|
309
421
|
> {
|
|
310
422
|
const newBaseBuilder = this.#baseBuilder.providesService<TServiceName, TService>(
|
|
311
423
|
serviceName,
|
|
312
424
|
fn,
|
|
313
425
|
);
|
|
314
426
|
|
|
315
|
-
return new DatabaseFragmentDefinitionBuilder(
|
|
427
|
+
return new DatabaseFragmentDefinitionBuilder(
|
|
428
|
+
newBaseBuilder,
|
|
429
|
+
this.#schema,
|
|
430
|
+
this.#namespace,
|
|
431
|
+
this.#hooksFactory,
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Provide a private service that is only accessible to the fragment author.
|
|
437
|
+
* Private services are NOT exposed on the fragment instance, but can be used
|
|
438
|
+
* when defining other services (baseServices, namedServices, and other privateServices).
|
|
439
|
+
* Private services are instantiated in order, so earlier private services are available
|
|
440
|
+
* to later ones.
|
|
441
|
+
*/
|
|
442
|
+
providesPrivateService<TServiceName extends string, TService>(
|
|
443
|
+
serviceName: TServiceName,
|
|
444
|
+
fn: ServiceConstructorFn<
|
|
445
|
+
TConfig,
|
|
446
|
+
FragnoPublicConfigWithDatabase,
|
|
447
|
+
TDeps,
|
|
448
|
+
TServiceDependencies,
|
|
449
|
+
TPrivateServices,
|
|
450
|
+
TService,
|
|
451
|
+
TServiceThisContext
|
|
452
|
+
>,
|
|
453
|
+
): DatabaseFragmentDefinitionBuilder<
|
|
454
|
+
TSchema,
|
|
455
|
+
TConfig,
|
|
456
|
+
TDeps,
|
|
457
|
+
TBaseServices,
|
|
458
|
+
TServices,
|
|
459
|
+
TServiceDependencies,
|
|
460
|
+
TPrivateServices & { [K in TServiceName]: TService },
|
|
461
|
+
THooks,
|
|
462
|
+
TServiceThisContext,
|
|
463
|
+
THandlerThisContext,
|
|
464
|
+
TLinkedFragments
|
|
465
|
+
> {
|
|
466
|
+
const newBaseBuilder = this.#baseBuilder.providesPrivateService<TServiceName, TService>(
|
|
467
|
+
serviceName,
|
|
468
|
+
fn,
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
return new DatabaseFragmentDefinitionBuilder(
|
|
472
|
+
newBaseBuilder,
|
|
473
|
+
this.#schema,
|
|
474
|
+
this.#namespace,
|
|
475
|
+
this.#hooksFactory,
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Define durable hooks for this fragment.
|
|
481
|
+
* Hooks are automatically persisted and retried on failure.
|
|
482
|
+
*
|
|
483
|
+
* @param fn - Function that receives defineHook helper and returns a hooks map
|
|
484
|
+
* @returns Builder with hooks type set
|
|
485
|
+
*
|
|
486
|
+
* @example
|
|
487
|
+
* ```ts
|
|
488
|
+
* .provideHooks(({ defineHook, config }) => ({
|
|
489
|
+
* onSubscribe: defineHook(async function (payload: { email: string }) {
|
|
490
|
+
* // 'this' context available (HookServiceContext with nonce)
|
|
491
|
+
* await config.onSubscribe?.(payload.email);
|
|
492
|
+
* }),
|
|
493
|
+
* }))
|
|
494
|
+
* ```
|
|
495
|
+
*/
|
|
496
|
+
provideHooks<TNewHooks extends HooksMap>(
|
|
497
|
+
fn: (context: {
|
|
498
|
+
config: TConfig;
|
|
499
|
+
options: FragnoPublicConfigWithDatabase;
|
|
500
|
+
defineHook: <TPayload>(
|
|
501
|
+
hook: (this: HookContext, payload: TPayload) => void | Promise<void>,
|
|
502
|
+
) => HookFn<TPayload>;
|
|
503
|
+
}) => TNewHooks,
|
|
504
|
+
): DatabaseFragmentDefinitionBuilder<
|
|
505
|
+
TSchema,
|
|
506
|
+
TConfig,
|
|
507
|
+
TDeps,
|
|
508
|
+
TBaseServices,
|
|
509
|
+
TServices,
|
|
510
|
+
TServiceDependencies,
|
|
511
|
+
TPrivateServices,
|
|
512
|
+
TNewHooks,
|
|
513
|
+
DatabaseServiceContext<TNewHooks>,
|
|
514
|
+
THandlerThisContext,
|
|
515
|
+
TLinkedFragments
|
|
516
|
+
> {
|
|
517
|
+
const defineHook = <TPayload>(
|
|
518
|
+
hook: (this: HookContext, payload: TPayload) => void | Promise<void>,
|
|
519
|
+
): HookFn<TPayload> => {
|
|
520
|
+
return hook;
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
// Store the hooks factory - it will be called in build() with config/options
|
|
524
|
+
const hooksFactory = (context: {
|
|
525
|
+
config: TConfig;
|
|
526
|
+
options: FragnoPublicConfigWithDatabase;
|
|
527
|
+
}) => {
|
|
528
|
+
return fn({
|
|
529
|
+
config: context.config,
|
|
530
|
+
options: context.options,
|
|
531
|
+
defineHook,
|
|
532
|
+
});
|
|
533
|
+
};
|
|
534
|
+
|
|
535
|
+
// Create new builder with hooks factory stored
|
|
536
|
+
// Cast is safe: we're only changing THooks and TServiceThisContext type parameters
|
|
537
|
+
const newBuilder = new DatabaseFragmentDefinitionBuilder(
|
|
538
|
+
this.#baseBuilder,
|
|
539
|
+
this.#schema,
|
|
540
|
+
this.#namespace,
|
|
541
|
+
) as unknown as DatabaseFragmentDefinitionBuilder<
|
|
542
|
+
TSchema,
|
|
543
|
+
TConfig,
|
|
544
|
+
TDeps,
|
|
545
|
+
TBaseServices,
|
|
546
|
+
TServices,
|
|
547
|
+
TServiceDependencies,
|
|
548
|
+
TPrivateServices,
|
|
549
|
+
TNewHooks,
|
|
550
|
+
DatabaseServiceContext<TNewHooks>,
|
|
551
|
+
THandlerThisContext,
|
|
552
|
+
TLinkedFragments
|
|
553
|
+
>;
|
|
554
|
+
|
|
555
|
+
newBuilder.#hooksFactory = hooksFactory;
|
|
556
|
+
|
|
557
|
+
return newBuilder;
|
|
316
558
|
}
|
|
317
559
|
|
|
318
560
|
/**
|
|
@@ -329,12 +571,19 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
329
571
|
TServices,
|
|
330
572
|
TServiceDependencies & { [K in TServiceName]: TService },
|
|
331
573
|
TPrivateServices,
|
|
574
|
+
THooks,
|
|
332
575
|
TServiceThisContext,
|
|
333
|
-
THandlerThisContext
|
|
576
|
+
THandlerThisContext,
|
|
577
|
+
TLinkedFragments
|
|
334
578
|
> {
|
|
335
579
|
const newBaseBuilder = this.#baseBuilder.usesService<TServiceName, TService>(serviceName);
|
|
336
580
|
|
|
337
|
-
return new DatabaseFragmentDefinitionBuilder(
|
|
581
|
+
return new DatabaseFragmentDefinitionBuilder(
|
|
582
|
+
newBaseBuilder,
|
|
583
|
+
this.#schema,
|
|
584
|
+
this.#namespace,
|
|
585
|
+
this.#hooksFactory,
|
|
586
|
+
);
|
|
338
587
|
}
|
|
339
588
|
|
|
340
589
|
/**
|
|
@@ -351,14 +600,21 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
351
600
|
TServices,
|
|
352
601
|
TServiceDependencies & { [K in TServiceName]: TService | undefined },
|
|
353
602
|
TPrivateServices,
|
|
603
|
+
THooks,
|
|
354
604
|
TServiceThisContext,
|
|
355
|
-
THandlerThisContext
|
|
605
|
+
THandlerThisContext,
|
|
606
|
+
TLinkedFragments
|
|
356
607
|
> {
|
|
357
608
|
const newBaseBuilder = this.#baseBuilder.usesOptionalService<TServiceName, TService>(
|
|
358
609
|
serviceName,
|
|
359
610
|
);
|
|
360
611
|
|
|
361
|
-
return new DatabaseFragmentDefinitionBuilder(
|
|
612
|
+
return new DatabaseFragmentDefinitionBuilder(
|
|
613
|
+
newBaseBuilder,
|
|
614
|
+
this.#schema,
|
|
615
|
+
this.#namespace,
|
|
616
|
+
this.#hooksFactory,
|
|
617
|
+
);
|
|
362
618
|
}
|
|
363
619
|
|
|
364
620
|
/**
|
|
@@ -374,18 +630,38 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
374
630
|
TServices,
|
|
375
631
|
TServiceDependencies,
|
|
376
632
|
TPrivateServices,
|
|
377
|
-
DatabaseServiceContext
|
|
378
|
-
DatabaseHandlerContext
|
|
379
|
-
DatabaseRequestStorage
|
|
633
|
+
DatabaseServiceContext<THooks>,
|
|
634
|
+
DatabaseHandlerContext<THooks>,
|
|
635
|
+
DatabaseRequestStorage,
|
|
636
|
+
TLinkedFragments
|
|
380
637
|
> {
|
|
638
|
+
const baseDef = this.#baseBuilder.build();
|
|
639
|
+
|
|
381
640
|
// Ensure dependencies callback always exists for database fragments
|
|
382
641
|
// If no user dependencies were defined, create a minimal one that only adds implicit deps
|
|
383
642
|
const dependencies = (context: {
|
|
384
643
|
config: TConfig;
|
|
385
644
|
options: FragnoPublicConfigWithDatabase;
|
|
386
645
|
}): TDeps => {
|
|
387
|
-
|
|
388
|
-
|
|
646
|
+
// In dry run mode, allow user deps to fail gracefully.
|
|
647
|
+
// This is critical for database fragments because the CLI needs access to the schema
|
|
648
|
+
// even when user dependencies (like API clients) can't be initialized.
|
|
649
|
+
// Without this, if user deps fail, we'd lose the implicit database dependencies
|
|
650
|
+
// (including schema), and the CLI couldn't extract schema information.
|
|
651
|
+
let userDeps;
|
|
652
|
+
try {
|
|
653
|
+
userDeps = baseDef.dependencies?.(context);
|
|
654
|
+
} catch (error) {
|
|
655
|
+
if (process.env["FRAGNO_INIT_DRY_RUN"] === "true") {
|
|
656
|
+
console.warn(
|
|
657
|
+
"Warning: Failed to initialize user dependencies in dry run mode:",
|
|
658
|
+
error instanceof Error ? error.message : String(error),
|
|
659
|
+
);
|
|
660
|
+
userDeps = {};
|
|
661
|
+
} else {
|
|
662
|
+
throw error;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
389
665
|
|
|
390
666
|
const { db } = createDatabaseContext(context.options, this.#schema, this.#namespace);
|
|
391
667
|
|
|
@@ -423,15 +699,29 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
423
699
|
},
|
|
424
700
|
);
|
|
425
701
|
|
|
426
|
-
//
|
|
702
|
+
// Get the internal fragment factory from linked fragments (added by withDatabase)
|
|
703
|
+
// Cast is safe: withDatabase() guarantees this fragment exists and has the correct type
|
|
704
|
+
const internalFragmentFactory = baseDef.linkedFragments?.["_fragno_internal"] as (context: {
|
|
705
|
+
config: TConfig;
|
|
706
|
+
options: FragnoPublicConfigWithDatabase;
|
|
707
|
+
}) => InternalFragmentInstance;
|
|
708
|
+
|
|
427
709
|
const builderWithContext = builderWithStorage.withThisContext<
|
|
428
|
-
DatabaseServiceContext
|
|
429
|
-
DatabaseHandlerContext
|
|
430
|
-
>(({ storage }) => {
|
|
431
|
-
//
|
|
710
|
+
DatabaseServiceContext<THooks>,
|
|
711
|
+
DatabaseHandlerContext<THooks>
|
|
712
|
+
>(({ storage, config, options }) => {
|
|
713
|
+
// Create hooks config if hooks factory is defined
|
|
714
|
+
const hooksConfig = this.#hooksFactory
|
|
715
|
+
? {
|
|
716
|
+
hooks: this.#hooksFactory({ config, options }),
|
|
717
|
+
namespace: this.#namespace,
|
|
718
|
+
internalFragment: internalFragmentFactory({ config, options }),
|
|
719
|
+
}
|
|
720
|
+
: undefined;
|
|
721
|
+
|
|
432
722
|
function forSchema<TSchema extends AnySchema>(
|
|
433
723
|
schema: TSchema,
|
|
434
|
-
): TypedUnitOfWork<TSchema, [], unknown> {
|
|
724
|
+
): TypedUnitOfWork<TSchema, [], unknown, THooks> {
|
|
435
725
|
const uow = storage.getStore()?.uow;
|
|
436
726
|
if (!uow) {
|
|
437
727
|
throw new Error(
|
|
@@ -439,24 +729,44 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
439
729
|
);
|
|
440
730
|
}
|
|
441
731
|
|
|
442
|
-
|
|
443
|
-
return uow.restrict().forSchema(schema);
|
|
732
|
+
return uow.restrict().forSchema<TSchema, THooks>(schema);
|
|
444
733
|
}
|
|
445
734
|
|
|
446
|
-
const
|
|
735
|
+
const serviceTx = async <
|
|
736
|
+
TSchema extends AnySchema,
|
|
737
|
+
TRetrievalResults extends unknown[],
|
|
738
|
+
TMutationResult = void,
|
|
739
|
+
>(
|
|
740
|
+
schema: TSchema,
|
|
741
|
+
callbacks: ServiceTxCallbacks<TSchema, TRetrievalResults, TMutationResult, THooks>,
|
|
742
|
+
): Promise<AwaitedPromisesInObject<TMutationResult>> => {
|
|
743
|
+
const uow = storage.getStore()?.uow;
|
|
744
|
+
if (!uow) {
|
|
745
|
+
throw new Error(
|
|
746
|
+
"No UnitOfWork in context. Service must be called within a route handler OR using `withUnitOfWork`.",
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
return executeServiceTx(schema, callbacks, uow);
|
|
751
|
+
};
|
|
752
|
+
|
|
753
|
+
const serviceContext: DatabaseServiceContext<THooks> = {
|
|
447
754
|
uow: forSchema,
|
|
755
|
+
tx: serviceTx,
|
|
448
756
|
};
|
|
449
757
|
|
|
450
|
-
// Handler context - only executeRestrictedUnitOfWork
|
|
451
758
|
async function uow<TResult>(
|
|
452
759
|
callback: (context: {
|
|
453
|
-
forSchema: <S extends AnySchema
|
|
760
|
+
forSchema: <S extends AnySchema, H extends HooksMap = THooks>(
|
|
761
|
+
schema: S,
|
|
762
|
+
hooks?: H,
|
|
763
|
+
) => TypedUnitOfWork<S, [], unknown, H>;
|
|
454
764
|
executeRetrieve: () => Promise<void>;
|
|
455
765
|
executeMutate: () => Promise<void>;
|
|
456
766
|
nonce: string;
|
|
457
767
|
currentAttempt: number;
|
|
458
768
|
}) => Promise<TResult> | TResult,
|
|
459
|
-
|
|
769
|
+
execOptions?: Omit<ExecuteRestrictedUnitOfWorkOptions, "createUnitOfWork">,
|
|
460
770
|
): Promise<AwaitedPromisesInObject<TResult>> {
|
|
461
771
|
const currentStorage = storage.getStore();
|
|
462
772
|
if (!currentStorage) {
|
|
@@ -465,30 +775,131 @@ export class DatabaseFragmentDefinitionBuilder<
|
|
|
465
775
|
);
|
|
466
776
|
}
|
|
467
777
|
|
|
468
|
-
// Wrap callback to ensure it always returns a Promise
|
|
469
778
|
const wrappedCallback = async (context: {
|
|
470
|
-
forSchema: <S extends AnySchema
|
|
779
|
+
forSchema: <S extends AnySchema, H extends HooksMap = THooks>(
|
|
780
|
+
schema: S,
|
|
781
|
+
hooks?: H,
|
|
782
|
+
) => TypedUnitOfWork<S, [], unknown, H>;
|
|
471
783
|
executeRetrieve: () => Promise<void>;
|
|
472
784
|
executeMutate: () => Promise<void>;
|
|
473
785
|
nonce: string;
|
|
474
786
|
currentAttempt: number;
|
|
475
787
|
}): Promise<TResult> => {
|
|
476
|
-
return
|
|
788
|
+
return callback(context);
|
|
477
789
|
};
|
|
478
790
|
|
|
479
|
-
|
|
480
|
-
|
|
791
|
+
const userOnBeforeMutate = execOptions?.onBeforeMutate;
|
|
792
|
+
const userOnSuccess = execOptions?.onSuccess;
|
|
793
|
+
|
|
481
794
|
return executeRestrictedUnitOfWork(wrappedCallback, {
|
|
482
|
-
...
|
|
795
|
+
...execOptions,
|
|
483
796
|
createUnitOfWork: () => {
|
|
484
797
|
currentStorage.uow.reset();
|
|
798
|
+
if (hooksConfig) {
|
|
799
|
+
currentStorage.uow.registerSchema(
|
|
800
|
+
hooksConfig.internalFragment.$internal.deps.schema,
|
|
801
|
+
hooksConfig.internalFragment.$internal.deps.namespace,
|
|
802
|
+
);
|
|
803
|
+
}
|
|
804
|
+
// Safe cast: currentStorage.uow is always a UnitOfWork instance
|
|
485
805
|
return currentStorage.uow as UnitOfWork;
|
|
486
806
|
},
|
|
807
|
+
onBeforeMutate: (uow) => {
|
|
808
|
+
if (hooksConfig) {
|
|
809
|
+
prepareHookMutations(uow, hooksConfig);
|
|
810
|
+
}
|
|
811
|
+
if (userOnBeforeMutate) {
|
|
812
|
+
userOnBeforeMutate(uow);
|
|
813
|
+
}
|
|
814
|
+
},
|
|
815
|
+
onSuccess: async (uow) => {
|
|
816
|
+
if (hooksConfig) {
|
|
817
|
+
await processHooks(hooksConfig);
|
|
818
|
+
}
|
|
819
|
+
if (userOnSuccess) {
|
|
820
|
+
await userOnSuccess(uow);
|
|
821
|
+
}
|
|
822
|
+
},
|
|
487
823
|
});
|
|
488
824
|
}
|
|
489
825
|
|
|
490
|
-
|
|
826
|
+
// Handler tx method with two overloads
|
|
827
|
+
function handlerTx<T extends readonly unknown[]>(
|
|
828
|
+
servicesFactory: () => readonly [...{ [K in keyof T]: Promise<T[K]> }],
|
|
829
|
+
execOptions?: Omit<ExecuteRestrictedUnitOfWorkOptions, "createUnitOfWork">,
|
|
830
|
+
): Promise<{ [K in keyof T]: T[K] }>;
|
|
831
|
+
function handlerTx<TRetrieveResult, TMutationResult>(
|
|
832
|
+
callbacks: HandlerTxCallbacks<TRetrieveResult, TMutationResult, THooks>,
|
|
833
|
+
execOptions?: Omit<ExecuteRestrictedUnitOfWorkOptions, "createUnitOfWork">,
|
|
834
|
+
): Promise<AwaitedPromisesInObject<TMutationResult>>;
|
|
835
|
+
async function handlerTx<T extends readonly unknown[], TRetrieveResult, TMutationResult>(
|
|
836
|
+
factoryOrCallbacks:
|
|
837
|
+
| (() => readonly [...{ [K in keyof T]: Promise<T[K]> }])
|
|
838
|
+
| HandlerTxCallbacks<TRetrieveResult, TMutationResult, THooks>,
|
|
839
|
+
execOptions?: Omit<ExecuteRestrictedUnitOfWorkOptions, "createUnitOfWork">,
|
|
840
|
+
): Promise<{ [K in keyof T]: T[K] } | AwaitedPromisesInObject<TMutationResult>> {
|
|
841
|
+
const currentStorage = storage.getStore();
|
|
842
|
+
if (!currentStorage) {
|
|
843
|
+
throw new Error(
|
|
844
|
+
"No storage in context. Handler must be called within a request context.",
|
|
845
|
+
);
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
const userOnBeforeMutate = execOptions?.onBeforeMutate;
|
|
849
|
+
const userOnSuccess = execOptions?.onSuccess;
|
|
850
|
+
|
|
851
|
+
const createUow = () => {
|
|
852
|
+
currentStorage.uow.reset();
|
|
853
|
+
|
|
854
|
+
if (hooksConfig) {
|
|
855
|
+
currentStorage.uow.registerSchema(
|
|
856
|
+
hooksConfig.internalFragment.$internal.deps.schema,
|
|
857
|
+
hooksConfig.internalFragment.$internal.deps.namespace,
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
// Safe cast: currentStorage.uow is always a UnitOfWork instance
|
|
861
|
+
return currentStorage.uow as UnitOfWork;
|
|
862
|
+
};
|
|
863
|
+
|
|
864
|
+
const options: ExecuteRestrictedUnitOfWorkOptions = {
|
|
865
|
+
...execOptions,
|
|
866
|
+
createUnitOfWork: createUow,
|
|
867
|
+
onBeforeMutate: (uow) => {
|
|
868
|
+
if (hooksConfig) {
|
|
869
|
+
prepareHookMutations(uow, hooksConfig);
|
|
870
|
+
}
|
|
871
|
+
if (userOnBeforeMutate) {
|
|
872
|
+
userOnBeforeMutate(uow);
|
|
873
|
+
}
|
|
874
|
+
},
|
|
875
|
+
onSuccess: async (uow) => {
|
|
876
|
+
if (hooksConfig) {
|
|
877
|
+
await processHooks(hooksConfig);
|
|
878
|
+
}
|
|
879
|
+
if (userOnSuccess) {
|
|
880
|
+
await userOnSuccess(uow);
|
|
881
|
+
}
|
|
882
|
+
},
|
|
883
|
+
};
|
|
884
|
+
|
|
885
|
+
// Check if it's a function (array syntax factory) or callbacks object (callback syntax)
|
|
886
|
+
if (typeof factoryOrCallbacks === "function") {
|
|
887
|
+
// Array syntax - factoryOrCallbacks is a factory function
|
|
888
|
+
return executeTxArray(
|
|
889
|
+
factoryOrCallbacks as () => readonly [...{ [K in keyof T]: Promise<T[K]> }],
|
|
890
|
+
options,
|
|
891
|
+
) as Promise<{ [K in keyof T]: T[K] }>;
|
|
892
|
+
} else {
|
|
893
|
+
return executeTxCallbacks(
|
|
894
|
+
factoryOrCallbacks as HandlerTxCallbacks<TRetrieveResult, TMutationResult, THooks>,
|
|
895
|
+
options,
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
const handlerContext: DatabaseHandlerContext<THooks> = {
|
|
491
901
|
uow,
|
|
902
|
+
tx: handlerTx,
|
|
492
903
|
};
|
|
493
904
|
|
|
494
905
|
return { serviceContext, handlerContext };
|