@fragno-dev/db 0.1.15 → 0.2.0
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 +23 -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 +53 -19
- package/dist/db-fragment-definition-builder.d.ts.map +1 -1
- package/dist/db-fragment-definition-builder.js +89 -19
- 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} +13 -3
- 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} +17 -4
- 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} +51 -18
- 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} +58 -11
- 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/create.d.ts +3 -0
- package/dist/schema/create.d.ts.map +1 -1
- package/dist/schema/create.js +4 -0
- package/dist/schema/create.js.map +1 -1
- 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 +37 -10
- package/src/adapters/adapters.ts +8 -5
- package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +60 -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 +281 -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 +184 -20
- package/src/hooks/hooks.test.ts +575 -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} +16 -16
- package/src/query/{execute-unit-of-work.ts → unit-of-work/execute-unit-of-work.ts} +49 -8
- package/src/query/{unit-of-work-coordinator.test.ts → unit-of-work/unit-of-work-coordinator.test.ts} +41 -43
- 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} +135 -32
- 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/create.ts +5 -0
- 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,19 +1,53 @@
|
|
|
1
1
|
import { AnyColumn, AnyRelation, Column, FragnoId, IdColumn, Index, Schema, Table } from "../schema/create.js";
|
|
2
|
+
import { RetryPolicy } from "../query/unit-of-work/retry-policy.js";
|
|
2
3
|
import { DatabaseHandlerContext, DatabaseRequestStorage, DatabaseServiceContext, FragnoPublicConfigWithDatabase, ImplicitDatabaseDependencies } from "../db-fragment-definition-builder.js";
|
|
3
4
|
import * as _fragno_dev_core0 from "@fragno-dev/core";
|
|
5
|
+
import { InstantiatedFragmentFromDefinition } from "@fragno-dev/core";
|
|
4
6
|
|
|
5
7
|
//#region src/fragments/internal-fragment.d.ts
|
|
6
|
-
declare const internalFragmentDef: _fragno_dev_core0.FragmentDefinition<{}, FragnoPublicConfigWithDatabase, ImplicitDatabaseDependencies<Schema<Record<"fragno_db_settings", Table<Record<string, AnyColumn> & Record<"id", IdColumn<"varchar(30)", string | FragnoId | null, FragnoId>> & Record<"key", Column<"string", string, string>> & Record<"value", Column<"string", string, string>>, Record<string, AnyRelation>, Record<string, Index<AnyColumn[], readonly string[]>> & Record<"unique_key", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["key"]>>>>>>, {}, {
|
|
8
|
+
declare const internalFragmentDef: _fragno_dev_core0.FragmentDefinition<{}, FragnoPublicConfigWithDatabase, ImplicitDatabaseDependencies<Schema<Record<"fragno_db_settings", Table<Record<string, AnyColumn> & Record<"id", IdColumn<"varchar(30)", string | FragnoId | null, FragnoId>> & Record<"key", Column<"string", string, string>> & Record<"value", Column<"string", string, string>>, Record<string, AnyRelation>, Record<string, Index<AnyColumn[], readonly string[]>> & Record<"unique_key", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["key"]>>>> & Record<"fragno_hooks", Table<Record<string, AnyColumn> & Record<"id", IdColumn<"varchar(30)", string | FragnoId | null, FragnoId>> & Record<"namespace", Column<"string", string, string>> & Record<"hookName", Column<"string", string, string>> & Record<"payload", Column<"json", unknown, unknown>> & Record<"status", Column<"string", string, string>> & Record<"attempts", Column<"integer", number | null, number>> & Record<"maxAttempts", Column<"integer", number | null, number>> & Record<"lastAttemptAt", Column<"timestamp", Date | null, Date | null>> & Record<"nextRetryAt", Column<"timestamp", Date | null, Date | null>> & Record<"error", Column<"string", string | null, string | null>> & Record<"createdAt", Column<"timestamp", Date | null, Date>> & Record<"nonce", Column<"string", string, string>>, Record<string, AnyRelation>, Record<string, Index<AnyColumn[], readonly string[]>> & Record<"idx_namespace_status_retry", Index<readonly [Column<"string", string, string>, Column<"string", string, string>, Column<"timestamp", Date | null, Date | null>] & AnyColumn[], readonly ["namespace", "status", "nextRetryAt"]>> & Record<"idx_nonce", Index<readonly [Column<"string", string, string>] & AnyColumn[], readonly ["nonce"]>>>>>>, {}, {
|
|
7
9
|
settingsService: {
|
|
8
|
-
get(key: string): Promise<{
|
|
10
|
+
get(namespace: string, key: string): Promise<{
|
|
9
11
|
id: FragnoId;
|
|
10
12
|
key: string;
|
|
11
13
|
value: string;
|
|
12
14
|
} | undefined>;
|
|
13
|
-
set(key: string, value: string): Promise<void>;
|
|
15
|
+
set(namespace: string, key: string, value: string): Promise<void>;
|
|
14
16
|
delete(id: FragnoId): Promise<void>;
|
|
15
17
|
};
|
|
16
|
-
}
|
|
18
|
+
} & {
|
|
19
|
+
hookService: {
|
|
20
|
+
/**
|
|
21
|
+
* Get pending hook events for processing.
|
|
22
|
+
* Returns all pending events for the given namespace that are ready to be processed.
|
|
23
|
+
*/
|
|
24
|
+
getPendingHookEvents(namespace: string): Promise<{
|
|
25
|
+
id: FragnoId;
|
|
26
|
+
hookName: string;
|
|
27
|
+
payload: unknown;
|
|
28
|
+
attempts: number;
|
|
29
|
+
maxAttempts: number;
|
|
30
|
+
nonce: string;
|
|
31
|
+
}[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Mark a hook event as completed.
|
|
34
|
+
*/
|
|
35
|
+
markHookCompleted(eventId: FragnoId): void;
|
|
36
|
+
/**
|
|
37
|
+
* Mark a hook event as failed and schedule next retry.
|
|
38
|
+
*/
|
|
39
|
+
markHookFailed(eventId: FragnoId, error: string, attempts: number, retryPolicy: RetryPolicy): void;
|
|
40
|
+
/**
|
|
41
|
+
* Mark a hook event as processing (to prevent concurrent execution).
|
|
42
|
+
*/
|
|
43
|
+
markHookProcessing(eventId: FragnoId): void;
|
|
44
|
+
};
|
|
45
|
+
}, {}, {}, DatabaseServiceContext<{}>, DatabaseHandlerContext<{}>, DatabaseRequestStorage, {}>;
|
|
46
|
+
/**
|
|
47
|
+
* Type representing an instantiated internal fragment.
|
|
48
|
+
* This is the fragment that manages Fragno's internal settings table.
|
|
49
|
+
*/
|
|
50
|
+
type InternalFragmentInstance = InstantiatedFragmentFromDefinition<typeof internalFragmentDef>;
|
|
17
51
|
//#endregion
|
|
18
|
-
export { internalFragmentDef };
|
|
52
|
+
export { InternalFragmentInstance, internalFragmentDef };
|
|
19
53
|
//# sourceMappingURL=internal-fragment.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-fragment.d.ts","names":[],"sources":["../../src/fragments/internal-fragment.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"internal-fragment.d.ts","names":[],"sources":["../../src/fragments/internal-fragment.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -5,35 +5,107 @@ import { DatabaseFragmentDefinitionBuilder } from "../db-fragment-definition-bui
|
|
|
5
5
|
//#region src/fragments/internal-fragment.ts
|
|
6
6
|
const SETTINGS_TABLE_NAME = "fragno_db_settings";
|
|
7
7
|
const SETTINGS_NAMESPACE = "fragno-db-settings";
|
|
8
|
-
const
|
|
8
|
+
const internalSchema = schema((s) => {
|
|
9
9
|
return s.addTable(SETTINGS_TABLE_NAME, (t) => {
|
|
10
10
|
return t.addColumn("id", idColumn()).addColumn("key", column("string")).addColumn("value", column("string")).createIndex("unique_key", ["key"], { unique: true });
|
|
11
|
+
}).addTable("fragno_hooks", (t) => {
|
|
12
|
+
return t.addColumn("id", idColumn()).addColumn("namespace", column("string")).addColumn("hookName", column("string")).addColumn("payload", column("json")).addColumn("status", column("string")).addColumn("attempts", column("integer").defaultTo(0)).addColumn("maxAttempts", column("integer").defaultTo(5)).addColumn("lastAttemptAt", column("timestamp").nullable()).addColumn("nextRetryAt", column("timestamp").nullable()).addColumn("error", column("string").nullable()).addColumn("createdAt", column("timestamp").defaultTo((b) => b.now())).addColumn("nonce", column("string")).createIndex("idx_namespace_status_retry", [
|
|
13
|
+
"namespace",
|
|
14
|
+
"status",
|
|
15
|
+
"nextRetryAt"
|
|
16
|
+
]).createIndex("idx_nonce", ["nonce"]);
|
|
11
17
|
});
|
|
12
18
|
});
|
|
13
|
-
const internalFragmentDef = new DatabaseFragmentDefinitionBuilder(new FragmentDefinitionBuilder("$fragno-internal-fragment"),
|
|
19
|
+
const internalFragmentDef = new DatabaseFragmentDefinitionBuilder(new FragmentDefinitionBuilder("$fragno-internal-fragment"), internalSchema, "").providesService("settingsService", ({ defineService }) => {
|
|
14
20
|
return defineService({
|
|
15
|
-
async get(key) {
|
|
16
|
-
const
|
|
21
|
+
async get(namespace, key) {
|
|
22
|
+
const fullKey = `${namespace}.${key}`;
|
|
23
|
+
const [results] = await this.uow(internalSchema).find(SETTINGS_TABLE_NAME, (b) => b.whereIndex("unique_key", (eb) => eb("key", "=", fullKey))).retrievalPhase;
|
|
17
24
|
return results?.[0];
|
|
18
25
|
},
|
|
19
|
-
async set(key, value) {
|
|
20
|
-
const
|
|
21
|
-
const
|
|
26
|
+
async set(namespace, key, value) {
|
|
27
|
+
const fullKey = `${namespace}.${key}`;
|
|
28
|
+
const uow = this.uow(internalSchema);
|
|
29
|
+
const [existing] = await uow.find(SETTINGS_TABLE_NAME, (b) => b.whereIndex("unique_key", (eb) => eb("key", "=", fullKey))).retrievalPhase;
|
|
22
30
|
if (existing?.[0]) uow.update(SETTINGS_TABLE_NAME, existing[0].id, (b) => b.set({ value }).check());
|
|
23
31
|
else uow.create(SETTINGS_TABLE_NAME, {
|
|
24
|
-
key:
|
|
32
|
+
key: fullKey,
|
|
25
33
|
value
|
|
26
34
|
});
|
|
27
35
|
await uow.mutationPhase;
|
|
28
36
|
},
|
|
29
37
|
async delete(id) {
|
|
30
|
-
const uow = this.uow(
|
|
38
|
+
const uow = this.uow(internalSchema);
|
|
31
39
|
uow.delete(SETTINGS_TABLE_NAME, id);
|
|
32
40
|
await uow.mutationPhase;
|
|
33
41
|
}
|
|
34
42
|
});
|
|
43
|
+
}).providesService("hookService", ({ defineService }) => {
|
|
44
|
+
return defineService({
|
|
45
|
+
async getPendingHookEvents(namespace) {
|
|
46
|
+
const [events] = await this.uow(internalSchema).find("fragno_hooks", (b) => b.whereIndex("idx_namespace_status_retry", (eb) => eb.and(eb("namespace", "=", namespace), eb("status", "=", "pending")))).retrievalPhase;
|
|
47
|
+
const now = /* @__PURE__ */ new Date();
|
|
48
|
+
return events.filter((event) => {
|
|
49
|
+
if (!event.nextRetryAt) return true;
|
|
50
|
+
return event.nextRetryAt <= now;
|
|
51
|
+
}).map((event) => ({
|
|
52
|
+
id: event.id,
|
|
53
|
+
hookName: event.hookName,
|
|
54
|
+
payload: event.payload,
|
|
55
|
+
attempts: event.attempts,
|
|
56
|
+
maxAttempts: event.maxAttempts,
|
|
57
|
+
nonce: event.nonce
|
|
58
|
+
}));
|
|
59
|
+
},
|
|
60
|
+
markHookCompleted(eventId) {
|
|
61
|
+
this.uow(internalSchema).update("fragno_hooks", eventId, (b) => b.set({
|
|
62
|
+
status: "completed",
|
|
63
|
+
lastAttemptAt: /* @__PURE__ */ new Date()
|
|
64
|
+
}).check());
|
|
65
|
+
},
|
|
66
|
+
markHookFailed(eventId, error, attempts, retryPolicy) {
|
|
67
|
+
const uow = this.uow(internalSchema);
|
|
68
|
+
const newAttempts = attempts + 1;
|
|
69
|
+
if (retryPolicy.shouldRetry(newAttempts - 1)) {
|
|
70
|
+
const delayMs = retryPolicy.getDelayMs(newAttempts - 1);
|
|
71
|
+
const nextRetryAt = new Date(Date.now() + delayMs);
|
|
72
|
+
uow.update("fragno_hooks", eventId, (b) => b.set({
|
|
73
|
+
status: "pending",
|
|
74
|
+
attempts: newAttempts,
|
|
75
|
+
lastAttemptAt: /* @__PURE__ */ new Date(),
|
|
76
|
+
nextRetryAt,
|
|
77
|
+
error
|
|
78
|
+
}).check());
|
|
79
|
+
} else uow.update("fragno_hooks", eventId, (b) => b.set({
|
|
80
|
+
status: "failed",
|
|
81
|
+
attempts: newAttempts,
|
|
82
|
+
lastAttemptAt: /* @__PURE__ */ new Date(),
|
|
83
|
+
error
|
|
84
|
+
}).check());
|
|
85
|
+
},
|
|
86
|
+
markHookProcessing(eventId) {
|
|
87
|
+
this.uow(internalSchema).update("fragno_hooks", eventId, (b) => b.set({
|
|
88
|
+
status: "processing",
|
|
89
|
+
lastAttemptAt: /* @__PURE__ */ new Date()
|
|
90
|
+
}).check());
|
|
91
|
+
}
|
|
92
|
+
});
|
|
35
93
|
}).build();
|
|
94
|
+
async function getSchemaVersionFromDatabase(fragment, namespace) {
|
|
95
|
+
try {
|
|
96
|
+
return await fragment.inContext(async function() {
|
|
97
|
+
const version = await this.uow(async ({ executeRetrieve }) => {
|
|
98
|
+
const version$1 = fragment.services.settingsService.get(namespace, "schema_version");
|
|
99
|
+
await executeRetrieve();
|
|
100
|
+
return version$1;
|
|
101
|
+
});
|
|
102
|
+
return version ? parseInt(version.value, 10) : 0;
|
|
103
|
+
});
|
|
104
|
+
} catch {
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
36
108
|
|
|
37
109
|
//#endregion
|
|
38
|
-
export { SETTINGS_NAMESPACE, SETTINGS_TABLE_NAME, internalFragmentDef,
|
|
110
|
+
export { SETTINGS_NAMESPACE, SETTINGS_TABLE_NAME, getSchemaVersionFromDatabase, internalFragmentDef, internalSchema };
|
|
39
111
|
//# sourceMappingURL=internal-fragment.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-fragment.js","names":[],"sources":["../../src/fragments/internal-fragment.ts"],"sourcesContent":["import { FragmentDefinitionBuilder } from \"@fragno-dev/core\";\nimport {\n DatabaseFragmentDefinitionBuilder,\n type DatabaseHandlerContext,\n type DatabaseRequestStorage,\n type DatabaseServiceContext,\n type FragnoPublicConfigWithDatabase,\n type ImplicitDatabaseDependencies,\n} from \"../db-fragment-definition-builder\";\nimport type { FragnoId } from \"../schema/create\";\nimport { schema, idColumn, column } from \"../schema/create\";\n\n// Constants for Fragno's internal settings table\nexport const SETTINGS_TABLE_NAME = \"fragno_db_settings\" as const;\nexport const SETTINGS_NAMESPACE = \"fragno-db-settings\" as const;\n\n// Settings schema for storing Fragno's internal key-value settings\nexport const settingsSchema = schema((s) => {\n return s.addTable(SETTINGS_TABLE_NAME, (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"key\", column(\"string\"))\n .addColumn(\"value\", column(\"string\"))\n .createIndex(\"unique_key\", [\"key\"], { unique: true });\n });\n});\n\n// This uses DatabaseFragmentDefinitionBuilder directly\n// to avoid circular dependency (it doesn't need to link to itself)\nexport const internalFragmentDef = new DatabaseFragmentDefinitionBuilder(\n new FragmentDefinitionBuilder<\n {},\n FragnoPublicConfigWithDatabase,\n ImplicitDatabaseDependencies<typeof settingsSchema>,\n {},\n {},\n {},\n {},\n DatabaseServiceContext,\n DatabaseHandlerContext,\n DatabaseRequestStorage\n >(\"$fragno-internal-fragment\"),\n settingsSchema,\n \"\", // intentionally blank namespace so there is no prefix\n)\n .providesService(\"settingsService\", ({ defineService }) => {\n return defineService({\n async get(key: string): Promise<{ id: FragnoId; key: string; value: string } | undefined> {\n const uow = this.uow(settingsSchema).find(SETTINGS_TABLE_NAME, (b) =>\n b.whereIndex(\"unique_key\", (eb) => eb(\"key\", \"=\", `${SETTINGS_NAMESPACE}.${key}`)),\n );\n const [results] = await uow.retrievalPhase;\n return results?.[0];\n },\n\n async set(key: string, value: string) {\n const uow = this.uow(settingsSchema);\n\n // First, find if the key already exists\n const findUow = uow.find(SETTINGS_TABLE_NAME, (b) =>\n b.whereIndex(\"unique_key\", (eb) => eb(\"key\", \"=\", `${SETTINGS_NAMESPACE}.${key}`)),\n );\n const [existing] = await findUow.retrievalPhase;\n\n if (existing?.[0]) {\n uow.update(SETTINGS_TABLE_NAME, existing[0].id, (b) => b.set({ value }).check());\n } else {\n uow.create(SETTINGS_TABLE_NAME, {\n key: `${SETTINGS_NAMESPACE}.${key}`,\n value,\n });\n }\n\n // Await mutation phase - will throw if mutation fails\n await uow.mutationPhase;\n },\n\n async delete(id: FragnoId) {\n const uow = this.uow(settingsSchema);\n uow.delete(SETTINGS_TABLE_NAME, id);\n await uow.mutationPhase;\n },\n });\n })\n .build();\n"],"mappings":";;;;;AAaA,MAAa,sBAAsB;AACnC,MAAa,qBAAqB;AAGlC,MAAa,iBAAiB,QAAQ,MAAM;AAC1C,QAAO,EAAE,SAAS,sBAAsB,MAAM;AAC5C,SAAO,EACJ,UAAU,MAAM,UAAU,CAAC,CAC3B,UAAU,OAAO,OAAO,SAAS,CAAC,CAClC,UAAU,SAAS,OAAO,SAAS,CAAC,CACpC,YAAY,cAAc,CAAC,MAAM,EAAE,EAAE,QAAQ,MAAM,CAAC;GACvD;EACF;AAIF,MAAa,sBAAsB,IAAI,kCACrC,IAAI,0BAWF,4BAA4B,EAC9B,gBACA,GACD,CACE,gBAAgB,oBAAoB,EAAE,oBAAoB;AACzD,QAAO,cAAc;EACnB,MAAM,IAAI,KAAgF;GAIxF,MAAM,CAAC,WAAW,MAHN,KAAK,IAAI,eAAe,CAAC,KAAK,sBAAsB,MAC9D,EAAE,WAAW,eAAe,OAAO,GAAG,OAAO,KAAK,GAAG,mBAAmB,GAAG,MAAM,CAAC,CACnF,CAC2B;AAC5B,UAAO,UAAU;;EAGnB,MAAM,IAAI,KAAa,OAAe;GACpC,MAAM,MAAM,KAAK,IAAI,eAAe;GAMpC,MAAM,CAAC,YAAY,MAHH,IAAI,KAAK,sBAAsB,MAC7C,EAAE,WAAW,eAAe,OAAO,GAAG,OAAO,KAAK,GAAG,mBAAmB,GAAG,MAAM,CAAC,CACnF,CACgC;AAEjC,OAAI,WAAW,GACb,KAAI,OAAO,qBAAqB,SAAS,GAAG,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC;OAEhF,KAAI,OAAO,qBAAqB;IAC9B,KAAK,GAAG,mBAAmB,GAAG;IAC9B;IACD,CAAC;AAIJ,SAAM,IAAI;;EAGZ,MAAM,OAAO,IAAc;GACzB,MAAM,MAAM,KAAK,IAAI,eAAe;AACpC,OAAI,OAAO,qBAAqB,GAAG;AACnC,SAAM,IAAI;;EAEb,CAAC;EACF,CACD,OAAO"}
|
|
1
|
+
{"version":3,"file":"internal-fragment.js","names":["version"],"sources":["../../src/fragments/internal-fragment.ts"],"sourcesContent":["import { FragmentDefinitionBuilder } from \"@fragno-dev/core\";\nimport type { InstantiatedFragmentFromDefinition } from \"@fragno-dev/core\";\nimport {\n DatabaseFragmentDefinitionBuilder,\n type DatabaseHandlerContext,\n type DatabaseRequestStorage,\n type DatabaseServiceContext,\n type FragnoPublicConfigWithDatabase,\n type ImplicitDatabaseDependencies,\n} from \"../db-fragment-definition-builder\";\nimport type { FragnoId } from \"../schema/create\";\nimport { schema, idColumn, column } from \"../schema/create\";\nimport type { RetryPolicy } from \"../query/unit-of-work/retry-policy\";\n\n// Constants for Fragno's internal settings table\nexport const SETTINGS_TABLE_NAME = \"fragno_db_settings\" as const;\n// FIXME: In some places we simply use empty string \"\" as namespace, which is not correct.\nexport const SETTINGS_NAMESPACE = \"fragno-db-settings\" as const;\n\nexport const internalSchema = schema((s) => {\n return s\n .addTable(SETTINGS_TABLE_NAME, (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"key\", column(\"string\"))\n .addColumn(\"value\", column(\"string\"))\n .createIndex(\"unique_key\", [\"key\"], { unique: true });\n })\n .addTable(\"fragno_hooks\", (t) => {\n return t\n .addColumn(\"id\", idColumn())\n .addColumn(\"namespace\", column(\"string\"))\n .addColumn(\"hookName\", column(\"string\"))\n .addColumn(\"payload\", column(\"json\"))\n .addColumn(\"status\", column(\"string\")) // \"pending\" | \"processing\" | \"completed\" | \"failed\"\n .addColumn(\"attempts\", column(\"integer\").defaultTo(0))\n .addColumn(\"maxAttempts\", column(\"integer\").defaultTo(5))\n .addColumn(\"lastAttemptAt\", column(\"timestamp\").nullable())\n .addColumn(\"nextRetryAt\", column(\"timestamp\").nullable())\n .addColumn(\"error\", column(\"string\").nullable())\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\"nonce\", column(\"string\"))\n .createIndex(\"idx_namespace_status_retry\", [\"namespace\", \"status\", \"nextRetryAt\"])\n .createIndex(\"idx_nonce\", [\"nonce\"]);\n });\n});\n\n// This uses DatabaseFragmentDefinitionBuilder directly\n// to avoid circular dependency (it doesn't need to link to itself)\nexport const internalFragmentDef = new DatabaseFragmentDefinitionBuilder(\n new FragmentDefinitionBuilder<\n {},\n FragnoPublicConfigWithDatabase,\n ImplicitDatabaseDependencies<typeof internalSchema>,\n {},\n {},\n {},\n {},\n DatabaseServiceContext<{}>,\n DatabaseHandlerContext,\n DatabaseRequestStorage\n >(\"$fragno-internal-fragment\"),\n internalSchema,\n \"\", // intentionally blank namespace so there is no prefix\n)\n .providesService(\"settingsService\", ({ defineService }) => {\n return defineService({\n async get(\n namespace: string,\n key: string,\n ): Promise<{ id: FragnoId; key: string; value: string } | undefined> {\n const fullKey = `${namespace}.${key}`;\n const uow = this.uow(internalSchema).find(SETTINGS_TABLE_NAME, (b) =>\n b.whereIndex(\"unique_key\", (eb) => eb(\"key\", \"=\", fullKey)),\n );\n const [results] = await uow.retrievalPhase;\n return results?.[0];\n },\n\n async set(namespace: string, key: string, value: string) {\n const fullKey = `${namespace}.${key}`;\n const uow = this.uow(internalSchema);\n\n // First, find if the key already exists\n const findUow = uow.find(SETTINGS_TABLE_NAME, (b) =>\n b.whereIndex(\"unique_key\", (eb) => eb(\"key\", \"=\", fullKey)),\n );\n const [existing] = await findUow.retrievalPhase;\n\n if (existing?.[0]) {\n uow.update(SETTINGS_TABLE_NAME, existing[0].id, (b) => b.set({ value }).check());\n } else {\n uow.create(SETTINGS_TABLE_NAME, {\n key: fullKey,\n value,\n });\n }\n\n // Await mutation phase - will throw if mutation fails\n await uow.mutationPhase;\n },\n\n async delete(id: FragnoId) {\n const uow = this.uow(internalSchema);\n uow.delete(SETTINGS_TABLE_NAME, id);\n await uow.mutationPhase;\n },\n });\n })\n .providesService(\"hookService\", ({ defineService }) => {\n // TODO(Wilco): re-implement this better\n return defineService({\n /**\n * Get pending hook events for processing.\n * Returns all pending events for the given namespace that are ready to be processed.\n */\n async getPendingHookEvents(namespace: string): Promise<\n {\n id: FragnoId;\n hookName: string;\n payload: unknown;\n attempts: number;\n maxAttempts: number;\n nonce: string;\n }[]\n > {\n const uow = this.uow(internalSchema).find(\"fragno_hooks\", (b) =>\n b.whereIndex(\"idx_namespace_status_retry\", (eb) =>\n eb.and(eb(\"namespace\", \"=\", namespace), eb(\"status\", \"=\", \"pending\")),\n ),\n );\n\n const [events] = await uow.retrievalPhase;\n\n // Filter for pending status and events ready for retry\n const now = new Date();\n const ready = events.filter((event) => {\n // FIXME(Wilco): this should be handled by the database query, but there seems to be an issue.\n if (!event.nextRetryAt) {\n return true; // Newly created events (nextRetryAt = null) are ready\n }\n return event.nextRetryAt <= now; // Only include if retry time has passed\n });\n\n return ready.map((event) => ({\n id: event.id,\n hookName: event.hookName,\n payload: event.payload,\n attempts: event.attempts,\n maxAttempts: event.maxAttempts,\n nonce: event.nonce,\n }));\n },\n\n /**\n * Mark a hook event as completed.\n */\n markHookCompleted(eventId: FragnoId): void {\n const uow = this.uow(internalSchema);\n uow.update(\"fragno_hooks\", eventId, (b) =>\n b.set({ status: \"completed\", lastAttemptAt: new Date() }).check(),\n );\n },\n\n /**\n * Mark a hook event as failed and schedule next retry.\n */\n markHookFailed(\n eventId: FragnoId,\n error: string,\n attempts: number,\n retryPolicy: RetryPolicy,\n ): void {\n const uow = this.uow(internalSchema);\n\n const newAttempts = attempts + 1;\n const shouldRetry = retryPolicy.shouldRetry(newAttempts - 1);\n\n if (shouldRetry) {\n const delayMs = retryPolicy.getDelayMs(newAttempts - 1);\n const nextRetryAt = new Date(Date.now() + delayMs);\n uow.update(\"fragno_hooks\", eventId, (b) =>\n b\n .set({\n status: \"pending\",\n attempts: newAttempts,\n lastAttemptAt: new Date(),\n nextRetryAt,\n error,\n })\n .check(),\n );\n } else {\n uow.update(\"fragno_hooks\", eventId, (b) =>\n b\n .set({\n status: \"failed\",\n attempts: newAttempts,\n lastAttemptAt: new Date(),\n error,\n })\n .check(),\n );\n }\n },\n\n /**\n * Mark a hook event as processing (to prevent concurrent execution).\n */\n markHookProcessing(eventId: FragnoId): void {\n const uow = this.uow(internalSchema);\n uow.update(\"fragno_hooks\", eventId, (b) =>\n b.set({ status: \"processing\", lastAttemptAt: new Date() }).check(),\n );\n },\n });\n })\n .build();\n\n/**\n * Type representing an instantiated internal fragment.\n * This is the fragment that manages Fragno's internal settings table.\n */\nexport type InternalFragmentInstance = InstantiatedFragmentFromDefinition<\n typeof internalFragmentDef\n>;\n\nexport async function getSchemaVersionFromDatabase(\n fragment: InternalFragmentInstance,\n namespace: string,\n): Promise<number> {\n try {\n const version = await fragment.inContext(async function () {\n const version = await this.uow(async ({ executeRetrieve }) => {\n const version = fragment.services.settingsService.get(namespace, \"schema_version\");\n await executeRetrieve();\n return version;\n });\n\n return version ? parseInt(version.value, 10) : 0;\n });\n return version;\n } catch {\n return 0;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { RetryPolicy } from "../query/unit-of-work/retry-policy.js";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/hooks.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Context available in hook functions via `this`.
|
|
7
|
+
* Contains the nonce for idempotency and database access.
|
|
8
|
+
*/
|
|
9
|
+
interface HookContext {
|
|
10
|
+
/**
|
|
11
|
+
* Unique nonce for this transaction.
|
|
12
|
+
* Use this for idempotency checks in your hook implementation.
|
|
13
|
+
*/
|
|
14
|
+
nonce: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A hook function signature.
|
|
18
|
+
* Hooks receive a typed payload and access context via `this`.
|
|
19
|
+
*/
|
|
20
|
+
type HookFn<TPayload = unknown> = (payload: TPayload) => void | Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Map of hook names to hook functions.
|
|
23
|
+
* Used for type-safe hook definitions and triggering.
|
|
24
|
+
*/
|
|
25
|
+
type HooksMap = Record<string, HookFn<any>>;
|
|
26
|
+
/**
|
|
27
|
+
* Extract the payload type from a hook function.
|
|
28
|
+
*/
|
|
29
|
+
type HookPayload<T> = T extends HookFn<infer P> ? P : never;
|
|
30
|
+
/**
|
|
31
|
+
* Options for triggering a hook.
|
|
32
|
+
*/
|
|
33
|
+
interface TriggerHookOptions {
|
|
34
|
+
/**
|
|
35
|
+
* Optional retry policy override for this specific hook trigger.
|
|
36
|
+
* If not provided, uses the default retry policy.
|
|
37
|
+
*/
|
|
38
|
+
retryPolicy?: RetryPolicy;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Internal representation of a triggered hook.
|
|
42
|
+
* Stored in the Unit of Work before execution.
|
|
43
|
+
*/
|
|
44
|
+
interface TriggeredHook {
|
|
45
|
+
hookName: string;
|
|
46
|
+
payload: unknown;
|
|
47
|
+
options?: TriggerHookOptions;
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { HookContext, HookFn, HookPayload, HooksMap, TriggerHookOptions, TriggeredHook };
|
|
51
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","names":[],"sources":["../../src/hooks/hooks.ts"],"sourcesContent":[],"mappings":";;;;AASA;AAYA;AAOA;AAKA;AAA6B,UAxBZ,WAAA,CAwBY;EAAU;;;AAKvC;EAYiB,KAAA,EAAA,MAAA;;;;;;KA7BL,uCAAuC,oBAAoB;;;;;KAO3D,QAAA,GAAW,eAAe;;;;KAK1B,iBAAiB,UAAU,kBAAkB;;;;UAKxC,kBAAA;;;;;gBAKD;;;;;;UAOC,aAAA;;;YAGL"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { ExponentialBackoffRetryPolicy } from "../query/unit-of-work/retry-policy.js";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/hooks.ts
|
|
4
|
+
/**
|
|
5
|
+
* Add hook events as mutation operations to the UOW.
|
|
6
|
+
* This should be called before executeMutations() so hook records are created
|
|
7
|
+
* in the same transaction as the user's mutations.
|
|
8
|
+
*/
|
|
9
|
+
function prepareHookMutations(uow, config) {
|
|
10
|
+
const { namespace, internalFragment, defaultRetryPolicy } = config;
|
|
11
|
+
const retryPolicy = defaultRetryPolicy ?? new ExponentialBackoffRetryPolicy({ maxRetries: 5 });
|
|
12
|
+
const triggeredHooks = uow.getTriggeredHooks();
|
|
13
|
+
if (triggeredHooks.length === 0) return;
|
|
14
|
+
const internalSchema = internalFragment.$internal.deps.schema;
|
|
15
|
+
const internalUow = uow.forSchema(internalSchema);
|
|
16
|
+
for (const hook of triggeredHooks) {
|
|
17
|
+
const maxAttempts = (hook.options?.retryPolicy ?? retryPolicy).shouldRetry(4) ? 5 : 1;
|
|
18
|
+
internalUow.create("fragno_hooks", {
|
|
19
|
+
namespace,
|
|
20
|
+
hookName: hook.hookName,
|
|
21
|
+
payload: hook.payload,
|
|
22
|
+
status: "pending",
|
|
23
|
+
attempts: 0,
|
|
24
|
+
maxAttempts,
|
|
25
|
+
lastAttemptAt: null,
|
|
26
|
+
nextRetryAt: null,
|
|
27
|
+
error: null,
|
|
28
|
+
nonce: uow.nonce
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Process pending hook events after the transaction has committed.
|
|
34
|
+
* This should be called in the onSuccess callback after executeMutations().
|
|
35
|
+
*/
|
|
36
|
+
async function processHooks(config) {
|
|
37
|
+
const { hooks, namespace, internalFragment, defaultRetryPolicy } = config;
|
|
38
|
+
const retryPolicy = defaultRetryPolicy ?? new ExponentialBackoffRetryPolicy({ maxRetries: 5 });
|
|
39
|
+
await internalFragment.inContext(async function() {
|
|
40
|
+
return await this.uow(async ({ executeRetrieve, executeMutate }) => {
|
|
41
|
+
const pendingEventsPromise = internalFragment.services.hookService.getPendingHookEvents(namespace);
|
|
42
|
+
await executeRetrieve();
|
|
43
|
+
const pendingEvents = await pendingEventsPromise;
|
|
44
|
+
if (pendingEvents.length === 0) return;
|
|
45
|
+
const processedEvents = await Promise.allSettled(pendingEvents.map(async (event) => {
|
|
46
|
+
const hookFn = hooks[event.hookName];
|
|
47
|
+
if (!hookFn) return {
|
|
48
|
+
eventId: event.id,
|
|
49
|
+
status: "failed",
|
|
50
|
+
error: `Hook '${event.hookName}' not found in hooks map`,
|
|
51
|
+
attempts: event.attempts,
|
|
52
|
+
maxAttempts: event.maxAttempts
|
|
53
|
+
};
|
|
54
|
+
try {
|
|
55
|
+
const hookContext = { nonce: event.nonce };
|
|
56
|
+
await hookFn.call(hookContext, event.payload);
|
|
57
|
+
return {
|
|
58
|
+
eventId: event.id,
|
|
59
|
+
status: "completed"
|
|
60
|
+
};
|
|
61
|
+
} catch (error) {
|
|
62
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
63
|
+
return {
|
|
64
|
+
eventId: event.id,
|
|
65
|
+
status: "failed",
|
|
66
|
+
error: errorMessage,
|
|
67
|
+
attempts: event.attempts,
|
|
68
|
+
maxAttempts: event.maxAttempts
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}));
|
|
72
|
+
for (const processedEvent of processedEvents) {
|
|
73
|
+
if (processedEvent.status === "rejected") continue;
|
|
74
|
+
const { eventId, status } = processedEvent.value;
|
|
75
|
+
if (status === "completed") internalFragment.services.hookService.markHookCompleted(eventId);
|
|
76
|
+
else if (status === "failed") {
|
|
77
|
+
const { error, attempts } = processedEvent.value;
|
|
78
|
+
internalFragment.services.hookService.markHookFailed(eventId, error, attempts, retryPolicy);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
await executeMutate();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
//#endregion
|
|
87
|
+
export { prepareHookMutations, processHooks };
|
|
88
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","names":["hookContext: HookContext"],"sources":["../../src/hooks/hooks.ts"],"sourcesContent":["import type { RetryPolicy } from \"../query/unit-of-work/retry-policy\";\nimport { ExponentialBackoffRetryPolicy } from \"../query/unit-of-work/retry-policy\";\nimport type { IUnitOfWork } from \"../query/unit-of-work/unit-of-work\";\nimport type { InternalFragmentInstance } from \"../fragments/internal-fragment\";\n\n/**\n * Context available in hook functions via `this`.\n * Contains the nonce for idempotency and database access.\n */\nexport interface HookContext {\n /**\n * Unique nonce for this transaction.\n * Use this for idempotency checks in your hook implementation.\n */\n nonce: string;\n}\n\n/**\n * A hook function signature.\n * Hooks receive a typed payload and access context via `this`.\n */\nexport type HookFn<TPayload = unknown> = (payload: TPayload) => void | Promise<void>;\n\n/**\n * Map of hook names to hook functions.\n * Used for type-safe hook definitions and triggering.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type HooksMap = Record<string, HookFn<any>>;\n\n/**\n * Extract the payload type from a hook function.\n */\nexport type HookPayload<T> = T extends HookFn<infer P> ? P : never;\n\n/**\n * Options for triggering a hook.\n */\nexport interface TriggerHookOptions {\n /**\n * Optional retry policy override for this specific hook trigger.\n * If not provided, uses the default retry policy.\n */\n retryPolicy?: RetryPolicy;\n}\n\n/**\n * Internal representation of a triggered hook.\n * Stored in the Unit of Work before execution.\n */\nexport interface TriggeredHook {\n hookName: string;\n payload: unknown;\n options?: TriggerHookOptions;\n}\n\n/**\n * Configuration for hook processing.\n */\nexport interface HookProcessorConfig {\n hooks: HooksMap;\n namespace: string;\n internalFragment: InternalFragmentInstance;\n defaultRetryPolicy?: RetryPolicy;\n}\n\n/**\n * Add hook events as mutation operations to the UOW.\n * This should be called before executeMutations() so hook records are created\n * in the same transaction as the user's mutations.\n */\nexport function prepareHookMutations(uow: IUnitOfWork, config: HookProcessorConfig): void {\n const { namespace, internalFragment, defaultRetryPolicy } = config;\n const retryPolicy = defaultRetryPolicy ?? new ExponentialBackoffRetryPolicy({ maxRetries: 5 });\n\n const triggeredHooks = uow.getTriggeredHooks();\n\n if (triggeredHooks.length === 0) {\n return;\n }\n\n const internalSchema = internalFragment.$internal.deps.schema;\n const internalUow = uow.forSchema(internalSchema);\n\n for (const hook of triggeredHooks) {\n const hookRetryPolicy = hook.options?.retryPolicy ?? retryPolicy;\n const maxAttempts = hookRetryPolicy.shouldRetry(4) ? 5 : 1;\n internalUow.create(\"fragno_hooks\", {\n namespace,\n hookName: hook.hookName,\n payload: hook.payload,\n status: \"pending\",\n attempts: 0,\n maxAttempts,\n lastAttemptAt: null,\n nextRetryAt: null,\n error: null,\n nonce: uow.nonce,\n });\n }\n}\n\n/**\n * Process pending hook events after the transaction has committed.\n * This should be called in the onSuccess callback after executeMutations().\n */\nexport async function processHooks(config: HookProcessorConfig): Promise<void> {\n const { hooks, namespace, internalFragment, defaultRetryPolicy } = config;\n const retryPolicy = defaultRetryPolicy ?? new ExponentialBackoffRetryPolicy({ maxRetries: 5 });\n\n await internalFragment.inContext(async function () {\n return await this.uow(async ({ executeRetrieve, executeMutate }) => {\n const pendingEventsPromise =\n internalFragment.services.hookService.getPendingHookEvents(namespace);\n await executeRetrieve();\n\n const pendingEvents = await pendingEventsPromise;\n\n if (pendingEvents.length === 0) {\n return;\n }\n\n const processedEvents = await Promise.allSettled(\n pendingEvents.map(async (event) => {\n const hookFn = hooks[event.hookName];\n if (!hookFn) {\n return {\n eventId: event.id,\n status: \"failed\" as const,\n error: `Hook '${event.hookName}' not found in hooks map`,\n attempts: event.attempts,\n maxAttempts: event.maxAttempts,\n };\n }\n\n try {\n const hookContext: HookContext = { nonce: event.nonce };\n await hookFn.call(hookContext, event.payload);\n return {\n eventId: event.id,\n status: \"completed\" as const,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n eventId: event.id,\n status: \"failed\" as const,\n error: errorMessage,\n attempts: event.attempts,\n maxAttempts: event.maxAttempts,\n };\n }\n }),\n );\n\n for (const processedEvent of processedEvents) {\n if (processedEvent.status === \"rejected\") {\n continue;\n }\n\n const { eventId, status } = processedEvent.value;\n\n if (status === \"completed\") {\n internalFragment.services.hookService.markHookCompleted(eventId);\n } else if (status === \"failed\") {\n const { error, attempts } = processedEvent.value;\n internalFragment.services.hookService.markHookFailed(\n eventId,\n error,\n attempts,\n retryPolicy,\n );\n }\n }\n\n await executeMutate();\n });\n });\n}\n"],"mappings":";;;;;;;;AAuEA,SAAgB,qBAAqB,KAAkB,QAAmC;CACxF,MAAM,EAAE,WAAW,kBAAkB,uBAAuB;CAC5D,MAAM,cAAc,sBAAsB,IAAI,8BAA8B,EAAE,YAAY,GAAG,CAAC;CAE9F,MAAM,iBAAiB,IAAI,mBAAmB;AAE9C,KAAI,eAAe,WAAW,EAC5B;CAGF,MAAM,iBAAiB,iBAAiB,UAAU,KAAK;CACvD,MAAM,cAAc,IAAI,UAAU,eAAe;AAEjD,MAAK,MAAM,QAAQ,gBAAgB;EAEjC,MAAM,eADkB,KAAK,SAAS,eAAe,aACjB,YAAY,EAAE,GAAG,IAAI;AACzD,cAAY,OAAO,gBAAgB;GACjC;GACA,UAAU,KAAK;GACf,SAAS,KAAK;GACd,QAAQ;GACR,UAAU;GACV;GACA,eAAe;GACf,aAAa;GACb,OAAO;GACP,OAAO,IAAI;GACZ,CAAC;;;;;;;AAQN,eAAsB,aAAa,QAA4C;CAC7E,MAAM,EAAE,OAAO,WAAW,kBAAkB,uBAAuB;CACnE,MAAM,cAAc,sBAAsB,IAAI,8BAA8B,EAAE,YAAY,GAAG,CAAC;AAE9F,OAAM,iBAAiB,UAAU,iBAAkB;AACjD,SAAO,MAAM,KAAK,IAAI,OAAO,EAAE,iBAAiB,oBAAoB;GAClE,MAAM,uBACJ,iBAAiB,SAAS,YAAY,qBAAqB,UAAU;AACvE,SAAM,iBAAiB;GAEvB,MAAM,gBAAgB,MAAM;AAE5B,OAAI,cAAc,WAAW,EAC3B;GAGF,MAAM,kBAAkB,MAAM,QAAQ,WACpC,cAAc,IAAI,OAAO,UAAU;IACjC,MAAM,SAAS,MAAM,MAAM;AAC3B,QAAI,CAAC,OACH,QAAO;KACL,SAAS,MAAM;KACf,QAAQ;KACR,OAAO,SAAS,MAAM,SAAS;KAC/B,UAAU,MAAM;KAChB,aAAa,MAAM;KACpB;AAGH,QAAI;KACF,MAAMA,cAA2B,EAAE,OAAO,MAAM,OAAO;AACvD,WAAM,OAAO,KAAK,aAAa,MAAM,QAAQ;AAC7C,YAAO;MACL,SAAS,MAAM;MACf,QAAQ;MACT;aACM,OAAO;KACd,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,YAAO;MACL,SAAS,MAAM;MACf,QAAQ;MACR,OAAO;MACP,UAAU,MAAM;MAChB,aAAa,MAAM;MACpB;;KAEH,CACH;AAED,QAAK,MAAM,kBAAkB,iBAAiB;AAC5C,QAAI,eAAe,WAAW,WAC5B;IAGF,MAAM,EAAE,SAAS,WAAW,eAAe;AAE3C,QAAI,WAAW,YACb,kBAAiB,SAAS,YAAY,kBAAkB,QAAQ;aACvD,WAAW,UAAU;KAC9B,MAAM,EAAE,OAAO,aAAa,eAAe;AAC3C,sBAAiB,SAAS,YAAY,eACpC,SACA,OACA,UACA,YACD;;;AAIL,SAAM,eAAe;IACrB;GACF"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AnySchema } from "../schema/create.js";
|
|
2
|
-
import { PreparedMigration } from "./create.js";
|
|
3
2
|
import { FragnoDatabase } from "../mod.js";
|
|
4
3
|
|
|
5
4
|
//#region src/migration-engine/generation-engine.d.ts
|
|
@@ -14,7 +13,6 @@ interface GenerationInternalResult {
|
|
|
14
13
|
namespace: string;
|
|
15
14
|
fromVersion: number;
|
|
16
15
|
toVersion: number;
|
|
17
|
-
preparedMigration?: PreparedMigration;
|
|
18
16
|
}
|
|
19
17
|
interface ExecuteMigrationResult {
|
|
20
18
|
namespace: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generation-engine.d.ts","names":[],"sources":["../../src/migration-engine/generation-engine.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generation-engine.d.ts","names":[],"sources":["../../src/migration-engine/generation-engine.ts"],"sourcesContent":[],"mappings":";;;;UAciB,sBAAA;;EAAA,IAAA,EAAA,MAAA;EAMA,SAAA,EAAA,MAAA;AAQjB;AAOsB,UAfL,wBAAA,CAe+B;EAEN,MAAA,EAAA,MAAA;EAAf,IAAA,EAAA,MAAA;EAEd,SAAA,EAAA,MAAA;EAMF,WAAA,EAAA,MAAA;EAAR,SAAA,EAAA,MAAA;;AA2ImB,UA5JL,sBAAA,CA4JsB;EAAyC,SAAA,EAAA,MAAA;EAAf,UAAA,EAAA,OAAA;EACpD,WAAA,EAAA,MAAA;EACF,SAAA,EAAA,MAAA;;AAAD,iBAvJY,0BAuJZ,CAAA,yBArJiB,cAqJjB,CArJgC,SAqJhC,EAAA,GAAA,CAAA,EAAA,CAAA,CAAA,SAAA,EAnJG,UAmJH,EAAA,QAAA,EAAA;EAiJM,IAAA,CAAA,EAAA,MAAA;;;IA9Rb,QAAQ;;;;;;;;iBA2IW,2CAA2C,eAAe,yBACnE,aACV,QAAQ;;;;;;;;;;;iBAiJK,6BAAA,QACP,6BACN"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { instantiate } from "../packages/fragno/dist/api/fragment-instantiator.js";
|
|
2
|
-
import { SETTINGS_NAMESPACE,
|
|
2
|
+
import { SETTINGS_NAMESPACE, getSchemaVersionFromDatabase, internalFragmentDef, internalSchema } from "../fragments/internal-fragment.js";
|
|
3
3
|
import { fragnoDatabaseAdapterNameFakeSymbol, fragnoDatabaseAdapterVersionFakeSymbol } from "../adapters/adapters.js";
|
|
4
4
|
|
|
5
5
|
//#region src/migration-engine/generation-engine.ts
|
|
@@ -11,7 +11,7 @@ async function generateMigrationsOrSchema(databases, options) {
|
|
|
11
11
|
if (options?.toVersion !== void 0 || options?.fromVersion !== void 0) console.warn("⚠️ Warning: --from and --to version options are not supported when generating schemas for multiple fragments and will be ignored.");
|
|
12
12
|
const fragmentsMap = /* @__PURE__ */ new Map();
|
|
13
13
|
fragmentsMap.set("", {
|
|
14
|
-
schema:
|
|
14
|
+
schema: internalSchema,
|
|
15
15
|
namespace: ""
|
|
16
16
|
});
|
|
17
17
|
for (const db of databases) if (!fragmentsMap.has(db.namespace)) fragmentsMap.set(db.namespace, {
|
|
@@ -24,53 +24,33 @@ async function generateMigrationsOrSchema(databases, options) {
|
|
|
24
24
|
namespace: firstDb.namespace
|
|
25
25
|
}];
|
|
26
26
|
}
|
|
27
|
-
if (!adapter.
|
|
27
|
+
if (!adapter.prepareMigrations) throw new Error("Adapter does not support migration-based schema generation. Ensure your adapter implements prepareMigrations.");
|
|
28
28
|
if (!await adapter.isConnectionHealthy()) throw new Error("Database connection is not healthy. Please check your database connection and try again.");
|
|
29
|
-
const
|
|
30
|
-
let settingsSourceVersion;
|
|
31
|
-
try {
|
|
32
|
-
const result = await internalFragment.inContext(async function() {
|
|
33
|
-
return await this.uow(async ({ executeRetrieve }) => {
|
|
34
|
-
const v = internalFragment.services.settingsService.get("version");
|
|
35
|
-
await executeRetrieve();
|
|
36
|
-
return v;
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
if (!result) settingsSourceVersion = 0;
|
|
40
|
-
else settingsSourceVersion = parseInt(result.value);
|
|
41
|
-
} catch {
|
|
42
|
-
settingsSourceVersion = 0;
|
|
43
|
-
}
|
|
29
|
+
const settingsSourceVersion = await getSchemaVersionFromDatabase(instantiate(internalFragmentDef).withConfig({}).withOptions({ databaseAdapter: adapter }).build(), SETTINGS_NAMESPACE);
|
|
44
30
|
const generatedFiles = [];
|
|
45
|
-
const
|
|
46
|
-
const settingsTargetVersion =
|
|
47
|
-
const
|
|
48
|
-
if (!settingsMigration.getSQL) throw new Error("Migration engine does not support SQL generation. Ensure your adapter's migration engine provides getSQL().");
|
|
49
|
-
const settingsSql = settingsMigration.getSQL();
|
|
31
|
+
const settingsPreparedMigrations = adapter.prepareMigrations(internalSchema, "");
|
|
32
|
+
const settingsTargetVersion = internalSchema.version;
|
|
33
|
+
const settingsSql = settingsPreparedMigrations.getSQL(settingsSourceVersion, settingsTargetVersion);
|
|
50
34
|
if (settingsSql.trim()) generatedFiles.push({
|
|
51
35
|
schema: settingsSql,
|
|
52
36
|
path: "settings-migration.sql",
|
|
53
37
|
namespace: "",
|
|
54
38
|
fromVersion: settingsSourceVersion,
|
|
55
|
-
toVersion: settingsTargetVersion
|
|
56
|
-
preparedMigration: settingsMigration
|
|
39
|
+
toVersion: settingsTargetVersion
|
|
57
40
|
});
|
|
58
41
|
for (const db of databases) {
|
|
59
42
|
const dbAdapter = db.adapter;
|
|
60
|
-
if (!dbAdapter.
|
|
61
|
-
const
|
|
43
|
+
if (!dbAdapter.prepareMigrations) throw new Error(`Adapter for ${db.namespace} does not support schema generation. Ensure your adapter implements either createSchemaGenerator or prepareMigrations.`);
|
|
44
|
+
const preparedMigrations = dbAdapter.prepareMigrations(db.schema, db.namespace);
|
|
62
45
|
const targetVersion = options?.toVersion ?? db.schema.version;
|
|
63
46
|
const sourceVersion = options?.fromVersion ?? 0;
|
|
64
|
-
const
|
|
65
|
-
if (!preparedMigration.getSQL) throw new Error("Migration engine does not support SQL generation. Ensure your adapter's migration engine provides getSQL().");
|
|
66
|
-
const sql = preparedMigration.getSQL();
|
|
47
|
+
const sql = preparedMigrations.getSQL(sourceVersion, targetVersion);
|
|
67
48
|
if (sql.trim()) generatedFiles.push({
|
|
68
49
|
schema: sql,
|
|
69
50
|
path: "schema.sql",
|
|
70
51
|
namespace: db.namespace,
|
|
71
52
|
fromVersion: sourceVersion,
|
|
72
|
-
toVersion: targetVersion
|
|
73
|
-
preparedMigration
|
|
53
|
+
toVersion: targetVersion
|
|
74
54
|
});
|
|
75
55
|
}
|
|
76
56
|
return postProcessMigrationFilenames(generatedFiles);
|
|
@@ -85,7 +65,7 @@ async function generateMigrationsOrSchema(databases, options) {
|
|
|
85
65
|
async function executeMigrations(databases) {
|
|
86
66
|
if (databases.length === 0) throw new Error("No databases provided for migration");
|
|
87
67
|
const adapter = databases[0].adapter;
|
|
88
|
-
if (!adapter.
|
|
68
|
+
if (!adapter.prepareMigrations) throw new Error("Adapter does not support running migrations. The adapter only supports schema generation.\nTry using 'generateMigrationsOrSchema' instead to generate schema files.");
|
|
89
69
|
const firstAdapterName = adapter[fragnoDatabaseAdapterNameFakeSymbol];
|
|
90
70
|
const firstAdapterVersion = adapter[fragnoDatabaseAdapterVersionFakeSymbol];
|
|
91
71
|
for (const db of databases) {
|
|
@@ -97,51 +77,33 @@ async function executeMigrations(databases) {
|
|
|
97
77
|
const results = [];
|
|
98
78
|
const migrationsToExecute = [];
|
|
99
79
|
const internalFragment = instantiate(internalFragmentDef).withConfig({}).withOptions({ databaseAdapter: adapter }).build();
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return this.uow(async ({ forSchema, executeRetrieve }) => {
|
|
104
|
-
const findOp = forSchema(settingsSchema).find(SETTINGS_TABLE_NAME, (b) => b.whereIndex("unique_key", (eb) => eb("key", "=", `${SETTINGS_NAMESPACE}.version`)));
|
|
105
|
-
await executeRetrieve();
|
|
106
|
-
const [results$1] = await findOp.retrievalPhase;
|
|
107
|
-
return results$1?.[0];
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
settingsSourceVersion = result ? parseInt(result.value) : 0;
|
|
111
|
-
} catch {
|
|
112
|
-
settingsSourceVersion = 0;
|
|
113
|
-
}
|
|
114
|
-
const settingsMigrator = adapter.createMigrationEngine(settingsSchema, "");
|
|
115
|
-
const settingsTargetVersion = settingsSchema.version;
|
|
80
|
+
const settingsSourceVersion = await getSchemaVersionFromDatabase(internalFragment, SETTINGS_NAMESPACE);
|
|
81
|
+
const settingsPreparedMigrations = adapter.prepareMigrations(internalSchema, "");
|
|
82
|
+
const settingsTargetVersion = internalSchema.version;
|
|
116
83
|
if (settingsSourceVersion < settingsTargetVersion) {
|
|
117
|
-
|
|
118
|
-
fromVersion: settingsSourceVersion,
|
|
119
|
-
updateSettings: true
|
|
120
|
-
});
|
|
121
|
-
if (settingsMigration.operations.length > 0) migrationsToExecute.push({
|
|
84
|
+
if (settingsPreparedMigrations.compile(settingsSourceVersion, settingsTargetVersion, { updateVersionInMigration: true }).statements.length > 0) migrationsToExecute.push({
|
|
122
85
|
namespace: "",
|
|
123
86
|
fromVersion: settingsSourceVersion,
|
|
124
87
|
toVersion: settingsTargetVersion,
|
|
125
|
-
|
|
88
|
+
execute: () => settingsPreparedMigrations.execute(settingsSourceVersion, settingsTargetVersion, { updateVersionInMigration: true })
|
|
126
89
|
});
|
|
127
90
|
}
|
|
128
91
|
const sortedDatabases = [...databases].sort((a, b) => a.namespace.localeCompare(b.namespace));
|
|
129
92
|
for (const fragnoDb of sortedDatabases) {
|
|
130
|
-
const
|
|
131
|
-
const currentVersion = await
|
|
93
|
+
const preparedMigrations = adapter.prepareMigrations(fragnoDb.schema, fragnoDb.namespace);
|
|
94
|
+
const currentVersion = await getSchemaVersionFromDatabase(internalFragment, fragnoDb.namespace);
|
|
132
95
|
const targetVersion = fragnoDb.schema.version;
|
|
133
96
|
if (currentVersion < targetVersion) {
|
|
134
|
-
|
|
135
|
-
if (preparedMigration.operations.length > 0) migrationsToExecute.push({
|
|
97
|
+
if (preparedMigrations.compile(currentVersion, targetVersion, { updateVersionInMigration: true }).statements.length > 0) migrationsToExecute.push({
|
|
136
98
|
namespace: fragnoDb.namespace,
|
|
137
99
|
fromVersion: currentVersion,
|
|
138
100
|
toVersion: targetVersion,
|
|
139
|
-
|
|
101
|
+
execute: () => preparedMigrations.execute(currentVersion, targetVersion, { updateVersionInMigration: true })
|
|
140
102
|
});
|
|
141
103
|
}
|
|
142
104
|
}
|
|
143
105
|
for (const migration of migrationsToExecute) {
|
|
144
|
-
await migration.
|
|
106
|
+
await migration.execute();
|
|
145
107
|
results.push({
|
|
146
108
|
namespace: migration.namespace,
|
|
147
109
|
didMigrate: true,
|