@fragno-dev/db 0.2.2 → 0.4.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 +404 -175
- package/CHANGELOG.md +109 -0
- package/README.md +54 -9
- package/dist/adapters/adapters.d.ts +23 -21
- package/dist/adapters/adapters.d.ts.map +1 -1
- package/dist/adapters/adapters.js.map +1 -1
- package/dist/adapters/generic-sql/driver-config.d.ts +16 -1
- package/dist/adapters/generic-sql/driver-config.d.ts.map +1 -1
- package/dist/adapters/generic-sql/driver-config.js +23 -1
- package/dist/adapters/generic-sql/driver-config.js.map +1 -1
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts +24 -9
- package/dist/adapters/generic-sql/generic-sql-adapter.d.ts.map +1 -1
- package/dist/adapters/generic-sql/generic-sql-adapter.js +60 -22
- package/dist/adapters/generic-sql/generic-sql-adapter.js.map +1 -1
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js +169 -3
- package/dist/adapters/generic-sql/generic-sql-uow-executor.js.map +1 -1
- package/dist/adapters/generic-sql/migration/cold-kysely.js.map +1 -1
- package/dist/adapters/generic-sql/migration/dialect/mysql.js +25 -6
- package/dist/adapters/generic-sql/migration/dialect/mysql.js.map +1 -1
- package/dist/adapters/generic-sql/migration/dialect/postgres.js +7 -6
- package/dist/adapters/generic-sql/migration/dialect/postgres.js.map +1 -1
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js +193 -16
- package/dist/adapters/generic-sql/migration/dialect/sqlite.js.map +1 -1
- package/dist/adapters/generic-sql/migration/executor.d.ts.map +1 -1
- package/dist/adapters/generic-sql/migration/executor.js +30 -3
- package/dist/adapters/generic-sql/migration/executor.js.map +1 -1
- package/dist/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -1
- package/dist/adapters/generic-sql/migration/prepared-migrations.js +9 -9
- package/dist/adapters/generic-sql/migration/prepared-migrations.js.map +1 -1
- package/dist/adapters/generic-sql/migration/sql-generator.js +75 -52
- package/dist/adapters/generic-sql/migration/sql-generator.js.map +1 -1
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js +7 -6
- package/dist/adapters/generic-sql/query/create-sql-query-compiler.js.map +1 -1
- package/dist/adapters/generic-sql/query/cursor-utils.js +42 -4
- package/dist/adapters/generic-sql/query/cursor-utils.js.map +1 -1
- package/dist/adapters/generic-sql/query/db-now-sql.js +27 -0
- package/dist/adapters/generic-sql/query/db-now-sql.js.map +1 -0
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js +32 -21
- package/dist/adapters/generic-sql/query/generic-sql-uow-operation-compiler.js.map +1 -1
- package/dist/adapters/generic-sql/query/select-builder.js +5 -3
- package/dist/adapters/generic-sql/query/select-builder.js.map +1 -1
- package/dist/adapters/generic-sql/query/sql-query-compiler.js +49 -18
- package/dist/adapters/generic-sql/query/sql-query-compiler.js.map +1 -1
- package/dist/adapters/generic-sql/query/where-builder.js +43 -29
- package/dist/adapters/generic-sql/query/where-builder.js.map +1 -1
- package/dist/adapters/generic-sql/sqlite-storage.d.ts +13 -0
- package/dist/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
- package/dist/adapters/generic-sql/sqlite-storage.js +15 -0
- package/dist/adapters/generic-sql/sqlite-storage.js.map +1 -0
- package/dist/adapters/generic-sql/uow-decoder.js +6 -2
- package/dist/adapters/generic-sql/uow-decoder.js.map +1 -1
- package/dist/adapters/generic-sql/uow-encoder.js +27 -8
- package/dist/adapters/generic-sql/uow-encoder.js.map +1 -1
- package/dist/adapters/in-memory/condition-evaluator.js +135 -0
- package/dist/adapters/in-memory/condition-evaluator.js.map +1 -0
- package/dist/adapters/in-memory/errors.d.ts +13 -0
- package/dist/adapters/in-memory/errors.d.ts.map +1 -0
- package/dist/adapters/in-memory/errors.js +23 -0
- package/dist/adapters/in-memory/errors.js.map +1 -0
- package/dist/adapters/in-memory/in-memory-adapter.d.ts +27 -0
- package/dist/adapters/in-memory/in-memory-adapter.d.ts.map +1 -0
- package/dist/adapters/in-memory/in-memory-adapter.js +196 -0
- package/dist/adapters/in-memory/in-memory-adapter.js.map +1 -0
- package/dist/adapters/in-memory/in-memory-uow.js +871 -0
- package/dist/adapters/in-memory/in-memory-uow.js.map +1 -0
- package/dist/adapters/in-memory/index.d.ts +4 -0
- package/dist/adapters/in-memory/index.js +4 -0
- package/dist/adapters/in-memory/options.d.ts +30 -0
- package/dist/adapters/in-memory/options.d.ts.map +1 -0
- package/dist/adapters/in-memory/options.js +62 -0
- package/dist/adapters/in-memory/options.js.map +1 -0
- package/dist/adapters/in-memory/reference-resolution.js +26 -0
- package/dist/adapters/in-memory/reference-resolution.js.map +1 -0
- package/dist/adapters/in-memory/sorted-array-index.js +129 -0
- package/dist/adapters/in-memory/sorted-array-index.js.map +1 -0
- package/dist/adapters/in-memory/store.js +71 -0
- package/dist/adapters/in-memory/store.js.map +1 -0
- package/dist/adapters/in-memory/value-comparison.js +28 -0
- package/dist/adapters/in-memory/value-comparison.js.map +1 -0
- package/dist/adapters/shared/from-unit-of-work-compiler.js +51 -24
- package/dist/adapters/shared/from-unit-of-work-compiler.js.map +1 -1
- package/dist/adapters/shared/uow-operation-compiler.js +11 -11
- package/dist/adapters/shared/uow-operation-compiler.js.map +1 -1
- package/dist/adapters/sql/index.d.ts +5 -0
- package/dist/adapters/sql/index.js +4 -0
- package/dist/browser/adapters/adapters.d.ts +61 -0
- package/dist/browser/adapters/adapters.d.ts.map +1 -0
- package/dist/browser/adapters/generic-sql/migration/executor.d.ts +15 -0
- package/dist/browser/adapters/generic-sql/migration/executor.d.ts.map +1 -0
- package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts +66 -0
- package/dist/browser/adapters/generic-sql/migration/prepared-migrations.d.ts.map +1 -0
- package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts +11 -0
- package/dist/browser/adapters/generic-sql/sqlite-storage.d.ts.map +1 -0
- package/dist/browser/adapters/in-memory/in-memory-adapter.d.ts +5 -0
- package/dist/browser/adapters/in-memory/index.d.ts +2 -0
- package/dist/browser/adapters/in-memory/options.d.ts +1 -0
- package/dist/browser/db-fragment-definition-builder.d.ts +237 -0
- package/dist/browser/db-fragment-definition-builder.d.ts.map +1 -0
- package/dist/browser/durable-hooks.d.ts +3 -0
- package/dist/browser/fragments/internal-fragment.d.ts +317 -0
- package/dist/browser/fragments/internal-fragment.d.ts.map +1 -0
- package/dist/browser/fragments/internal-fragment.schema.d.ts +1 -0
- package/dist/browser/hooks/durable-hooks-logger.d.ts +10 -0
- package/dist/browser/hooks/durable-hooks-logger.d.ts.map +1 -0
- package/dist/browser/hooks/hooks.d.ts +146 -0
- package/dist/browser/hooks/hooks.d.ts.map +1 -0
- package/dist/browser/id.js +1 -0
- package/dist/browser/internal/adapter-registry.d.ts +4 -0
- package/dist/browser/internal/outbox-state.d.ts +2 -0
- package/dist/browser/mod.d.ts +15 -0
- package/dist/browser/mod.d.ts.map +1 -0
- package/dist/browser/mod.js +17 -0
- package/dist/browser/mod.js.map +1 -0
- package/dist/browser/mod2.d.ts +48 -0
- package/dist/browser/mod2.d.ts.map +1 -0
- package/dist/browser/naming/sql-naming.d.ts +19 -0
- package/dist/browser/naming/sql-naming.d.ts.map +1 -0
- package/dist/browser/outbox/outbox.d.ts +21 -0
- package/dist/browser/outbox/outbox.d.ts.map +1 -0
- package/dist/browser/query/column-defaults.js +1 -0
- package/dist/browser/query/condition-builder.d.ts +44 -0
- package/dist/browser/query/condition-builder.d.ts.map +1 -0
- package/dist/browser/query/condition-builder.js +97 -0
- package/dist/browser/query/condition-builder.js.map +1 -0
- package/dist/browser/query/cursor.d.ts +105 -0
- package/dist/browser/query/cursor.d.ts.map +1 -0
- package/dist/browser/query/cursor.js +150 -0
- package/dist/browser/query/cursor.js.map +1 -0
- package/dist/browser/query/db-now.d.ts +22 -0
- package/dist/browser/query/db-now.d.ts.map +1 -0
- package/dist/browser/query/db-now.js +33 -0
- package/dist/browser/query/db-now.js.map +1 -0
- package/dist/browser/query/orm/orm.d.ts +18 -0
- package/dist/browser/query/orm/orm.d.ts.map +1 -0
- package/dist/browser/query/simple-query-interface.d.ts +108 -0
- package/dist/browser/query/simple-query-interface.d.ts.map +1 -0
- package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts +423 -0
- package/dist/browser/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -0
- package/dist/browser/query/unit-of-work/execute-unit-of-work.js +507 -0
- package/dist/browser/query/unit-of-work/execute-unit-of-work.js.map +1 -0
- package/dist/browser/query/unit-of-work/retry-policy.d.ts +23 -0
- package/dist/browser/query/unit-of-work/retry-policy.d.ts.map +1 -0
- package/dist/browser/query/unit-of-work/retry-policy.js +40 -0
- package/dist/browser/query/unit-of-work/retry-policy.js.map +1 -0
- package/dist/browser/query/unit-of-work/unit-of-work.d.ts +703 -0
- package/dist/browser/query/unit-of-work/unit-of-work.d.ts.map +1 -0
- package/dist/browser/query/unit-of-work/unit-of-work.js +1206 -0
- package/dist/browser/query/unit-of-work/unit-of-work.js.map +1 -0
- package/dist/browser/query/value-encoding.js +38 -0
- package/dist/browser/query/value-encoding.js.map +1 -0
- package/dist/browser/schema/create.d.ts +326 -0
- package/dist/browser/schema/create.d.ts.map +1 -0
- package/dist/browser/schema/create.js +89 -0
- package/dist/browser/schema/create.js.map +1 -0
- package/dist/browser/schema/generate-id.js +28 -0
- package/dist/browser/schema/generate-id.js.map +1 -0
- package/dist/browser/shared/providers.d.ts +6 -0
- package/dist/browser/shared/providers.d.ts.map +1 -0
- package/dist/browser/sql-driver/connection/connection-provider.d.ts +13 -0
- package/dist/browser/sql-driver/connection/connection-provider.d.ts.map +1 -0
- package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts +7 -0
- package/dist/browser/sql-driver/dialect-adapter/dialect-adapter.d.ts.map +1 -0
- package/dist/browser/sql-driver/driver/runtime-driver.d.ts +23 -0
- package/dist/browser/sql-driver/driver/runtime-driver.d.ts.map +1 -0
- package/dist/browser/sql-driver/query-executor/plugin.d.ts +17 -0
- package/dist/browser/sql-driver/query-executor/plugin.d.ts.map +1 -0
- package/dist/browser/sql-driver/query-executor/query-executor.d.ts +36 -0
- package/dist/browser/sql-driver/query-executor/query-executor.d.ts.map +1 -0
- package/dist/browser/sql-driver/sql-driver-adapter.d.ts +29 -0
- package/dist/browser/sql-driver/sql-driver-adapter.d.ts.map +1 -0
- package/dist/browser/sql-driver/sql-driver.d.ts +38 -0
- package/dist/browser/sql-driver/sql-driver.d.ts.map +1 -0
- package/dist/browser/sync/commands.d.ts +15 -0
- package/dist/browser/sync/commands.d.ts.map +1 -0
- package/dist/browser/sync/commands.js +27 -0
- package/dist/browser/sync/commands.js.map +1 -0
- package/dist/browser/sync/types.d.ts +63 -0
- package/dist/browser/sync/types.d.ts.map +1 -0
- package/dist/browser/util/types.d.ts +8 -0
- package/dist/browser/util/types.d.ts.map +1 -0
- package/dist/browser/with-database.d.ts +29 -0
- package/dist/browser/with-database.d.ts.map +1 -0
- package/dist/client.d.ts +4 -0
- package/dist/client.js +5 -0
- package/dist/db-fragment-definition-builder.d.ts +101 -33
- package/dist/db-fragment-definition-builder.d.ts.map +1 -1
- package/dist/db-fragment-definition-builder.js +450 -60
- package/dist/db-fragment-definition-builder.js.map +1 -1
- package/dist/dispatchers/cloudflare-do/dispatcher.d.ts +20 -0
- package/dist/dispatchers/cloudflare-do/dispatcher.d.ts.map +1 -0
- package/dist/dispatchers/cloudflare-do/dispatcher.js +147 -0
- package/dist/dispatchers/cloudflare-do/dispatcher.js.map +1 -0
- package/dist/dispatchers/cloudflare-do/index.d.ts +11 -0
- package/dist/dispatchers/cloudflare-do/index.d.ts.map +1 -0
- package/dist/dispatchers/cloudflare-do/index.js +31 -0
- package/dist/dispatchers/cloudflare-do/index.js.map +1 -0
- package/dist/dispatchers/node/dispatcher.d.ts +14 -0
- package/dist/dispatchers/node/dispatcher.d.ts.map +1 -0
- package/dist/dispatchers/node/dispatcher.js +80 -0
- package/dist/dispatchers/node/dispatcher.js.map +1 -0
- package/dist/dispatchers/node/index.d.ts +12 -0
- package/dist/dispatchers/node/index.d.ts.map +1 -0
- package/dist/dispatchers/node/index.js +27 -0
- package/dist/dispatchers/node/index.js.map +1 -0
- package/dist/durable-hooks.d.ts +31 -0
- package/dist/durable-hooks.d.ts.map +1 -0
- package/dist/durable-hooks.js +23 -0
- package/dist/durable-hooks.js.map +1 -0
- package/dist/fragments/internal-fragment.d.ts +186 -8
- package/dist/fragments/internal-fragment.d.ts.map +1 -1
- package/dist/fragments/internal-fragment.js +203 -38
- package/dist/fragments/internal-fragment.js.map +1 -1
- package/dist/fragments/internal-fragment.routes.js +164 -0
- package/dist/fragments/internal-fragment.routes.js.map +1 -0
- package/dist/fragments/internal-fragment.schema.d.ts +15 -0
- package/dist/fragments/internal-fragment.schema.d.ts.map +1 -0
- package/dist/fragments/internal-fragment.schema.js +39 -0
- package/dist/fragments/internal-fragment.schema.js.map +1 -0
- package/dist/hooks/durable-hooks-logger.d.ts +10 -0
- package/dist/hooks/durable-hooks-logger.d.ts.map +1 -0
- package/dist/hooks/durable-hooks-logger.js +75 -0
- package/dist/hooks/durable-hooks-logger.js.map +1 -0
- package/dist/hooks/durable-hooks-processor.d.ts +1 -0
- package/dist/hooks/durable-hooks-processor.js +80 -0
- package/dist/hooks/durable-hooks-processor.js.map +1 -0
- package/dist/hooks/durable-hooks-runtime.js +44 -0
- package/dist/hooks/durable-hooks-runtime.js.map +1 -0
- package/dist/hooks/hooks.d.ts +100 -1
- package/dist/hooks/hooks.d.ts.map +1 -1
- package/dist/hooks/hooks.js +254 -27
- package/dist/hooks/hooks.js.map +1 -1
- package/dist/id.d.ts +2 -2
- package/dist/id.js +2 -2
- package/dist/internal/adapter-registry.d.ts +11 -0
- package/dist/internal/adapter-registry.d.ts.map +1 -0
- package/dist/internal/adapter-registry.js +135 -0
- package/dist/internal/adapter-registry.js.map +1 -0
- package/dist/internal/outbox-state.d.ts +2 -0
- package/dist/internal/outbox-state.js +26 -0
- package/dist/internal/outbox-state.js.map +1 -0
- package/dist/migration-engine/auto-from-schema.d.ts +33 -0
- package/dist/migration-engine/auto-from-schema.d.ts.map +1 -0
- package/dist/migration-engine/auto-from-schema.js +223 -37
- package/dist/migration-engine/auto-from-schema.js.map +1 -1
- package/dist/migration-engine/generation-engine.d.ts +16 -10
- package/dist/migration-engine/generation-engine.d.ts.map +1 -1
- package/dist/migration-engine/generation-engine.js +86 -35
- package/dist/migration-engine/generation-engine.js.map +1 -1
- package/dist/migration-engine/shared.d.ts +113 -0
- package/dist/migration-engine/shared.d.ts.map +1 -0
- package/dist/migration-engine/shared.js.map +1 -1
- package/dist/mod.d.ts +20 -12
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +18 -12
- package/dist/mod.js.map +1 -1
- package/dist/naming/sql-naming.d.ts +19 -0
- package/dist/naming/sql-naming.d.ts.map +1 -0
- package/dist/naming/sql-naming.js +116 -0
- package/dist/naming/sql-naming.js.map +1 -0
- package/dist/outbox/outbox-builder.js +156 -0
- package/dist/outbox/outbox-builder.js.map +1 -0
- package/dist/outbox/outbox.d.ts +54 -0
- package/dist/outbox/outbox.d.ts.map +1 -0
- package/dist/outbox/outbox.js +37 -0
- package/dist/outbox/outbox.js.map +1 -0
- package/dist/query/column-defaults.js +20 -4
- package/dist/query/column-defaults.js.map +1 -1
- package/dist/query/condition-builder.d.ts +7 -1
- package/dist/query/condition-builder.d.ts.map +1 -1
- package/dist/query/condition-builder.js +5 -1
- package/dist/query/condition-builder.js.map +1 -1
- package/dist/query/cursor-client.d.ts +105 -0
- package/dist/query/cursor-client.d.ts.map +1 -0
- package/dist/query/cursor-client.js +165 -0
- package/dist/query/cursor-client.js.map +1 -0
- package/dist/query/cursor.d.ts +3 -1
- package/dist/query/cursor.d.ts.map +1 -1
- package/dist/query/cursor.js +51 -14
- package/dist/query/cursor.js.map +1 -1
- package/dist/query/db-now.d.ts +22 -0
- package/dist/query/db-now.d.ts.map +1 -0
- package/dist/query/db-now.js +35 -0
- package/dist/query/db-now.js.map +1 -0
- package/dist/query/orm/orm.js.map +1 -1
- package/dist/query/serialize/create-sql-serializer.js +5 -4
- package/dist/query/serialize/create-sql-serializer.js.map +1 -1
- package/dist/query/serialize/dialect/mysql-serializer.js +12 -6
- package/dist/query/serialize/dialect/mysql-serializer.js.map +1 -1
- package/dist/query/serialize/dialect/postgres-serializer.js +25 -7
- package/dist/query/serialize/dialect/postgres-serializer.js.map +1 -1
- package/dist/query/serialize/dialect/sqlite-serializer.js +60 -12
- package/dist/query/serialize/dialect/sqlite-serializer.js.map +1 -1
- package/dist/query/serialize/sql-serializer.js +2 -2
- package/dist/query/serialize/sql-serializer.js.map +1 -1
- package/dist/query/simple-query-interface.d.ts +13 -4
- package/dist/query/simple-query-interface.d.ts.map +1 -1
- package/dist/query/unit-of-work/execute-unit-of-work.d.ts +37 -2
- package/dist/query/unit-of-work/execute-unit-of-work.d.ts.map +1 -1
- package/dist/query/unit-of-work/execute-unit-of-work.js +50 -24
- package/dist/query/unit-of-work/execute-unit-of-work.js.map +1 -1
- package/dist/query/unit-of-work/unit-of-work.d.ts +92 -30
- package/dist/query/unit-of-work/unit-of-work.d.ts.map +1 -1
- package/dist/query/unit-of-work/unit-of-work.js +136 -11
- package/dist/query/unit-of-work/unit-of-work.js.map +1 -1
- package/dist/query/value-decoding.js +16 -6
- package/dist/query/value-decoding.js.map +1 -1
- package/dist/query/value-encoding.js +29 -9
- package/dist/query/value-encoding.js.map +1 -1
- package/dist/schema/create.d.ts +103 -35
- package/dist/schema/create.d.ts.map +1 -1
- package/dist/schema/create.js +172 -58
- package/dist/schema/create.js.map +1 -1
- package/dist/schema/generate-id.js +2 -2
- package/dist/schema/generate-id.js.map +1 -1
- package/dist/schema/type-conversion/create-sql-type-mapper.js +4 -3
- package/dist/schema/type-conversion/create-sql-type-mapper.js.map +1 -1
- package/dist/schema/type-conversion/dialect/sqlite.js +9 -0
- package/dist/schema/type-conversion/dialect/sqlite.js.map +1 -1
- package/dist/schema/validator.d.ts +10 -0
- package/dist/schema/validator.d.ts.map +1 -0
- package/dist/schema/validator.js +123 -0
- package/dist/schema/validator.js.map +1 -0
- package/dist/schema-output/drizzle.d.ts +30 -0
- package/dist/schema-output/drizzle.d.ts.map +1 -0
- package/dist/{adapters/drizzle/generate.js → schema-output/drizzle.js} +88 -60
- package/dist/schema-output/drizzle.js.map +1 -0
- package/dist/schema-output/prisma.d.ts +17 -0
- package/dist/schema-output/prisma.d.ts.map +1 -0
- package/dist/schema-output/prisma.js +307 -0
- package/dist/schema-output/prisma.js.map +1 -0
- package/dist/sql-driver/dialects/durable-object-dialect.js +3 -9
- package/dist/sql-driver/dialects/durable-object-dialect.js.map +1 -1
- package/dist/sql-driver/query-executor/default-query-executor.js.map +1 -1
- package/dist/sql-driver/query-executor/query-executor-base.js.map +1 -1
- package/dist/sql-driver/sql-driver-adapter.js.map +1 -1
- package/dist/sql-driver/sql.js.map +1 -1
- package/dist/sync/commands.d.ts +15 -0
- package/dist/sync/commands.d.ts.map +1 -0
- package/dist/sync/commands.js +27 -0
- package/dist/sync/commands.js.map +1 -0
- package/dist/sync/index.d.ts +4 -0
- package/dist/sync/index.js +4 -0
- package/dist/sync/read-tracking.d.ts +25 -0
- package/dist/sync/read-tracking.d.ts.map +1 -0
- package/dist/sync/read-tracking.js +148 -0
- package/dist/sync/read-tracking.js.map +1 -0
- package/dist/sync/submit.js +213 -0
- package/dist/sync/submit.js.map +1 -0
- package/dist/sync/types.d.ts +63 -0
- package/dist/sync/types.d.ts.map +1 -0
- package/dist/util/default-database-adapter.js +66 -0
- package/dist/util/default-database-adapter.js.map +1 -0
- package/dist/with-database.d.ts +3 -6
- package/dist/with-database.d.ts.map +1 -1
- package/dist/with-database.js +8 -7
- package/dist/with-database.js.map +1 -1
- package/package.json +62 -55
- package/src/adapters/adapters.ts +33 -26
- package/src/adapters/drizzle/migrate-drizzle.test.ts +99 -41
- package/src/adapters/drizzle/migration-parity-drizzle-kit.test.ts +601 -0
- package/src/adapters/drizzle/test-utils.ts +13 -8
- package/src/adapters/generic-sql/driver-config.ts +38 -0
- package/src/adapters/generic-sql/generic-sql-adapter.test.ts +10 -8
- package/src/adapters/generic-sql/generic-sql-adapter.ts +117 -34
- package/src/adapters/generic-sql/generic-sql-uow-executor.test.ts +55 -0
- package/src/adapters/generic-sql/generic-sql-uow-executor.ts +297 -3
- package/src/adapters/generic-sql/migration/adapter-migration-parity.test.ts +120 -0
- package/src/adapters/generic-sql/migration/cold-kysely.ts +1 -0
- package/src/adapters/generic-sql/migration/dialect/mysql.test.ts +27 -8
- package/src/adapters/generic-sql/migration/dialect/mysql.ts +47 -8
- package/src/adapters/generic-sql/migration/dialect/postgres.test.ts +28 -9
- package/src/adapters/generic-sql/migration/dialect/postgres.ts +9 -4
- package/src/adapters/generic-sql/migration/dialect/sqlite.test.ts +839 -8
- package/src/adapters/generic-sql/migration/dialect/sqlite.ts +396 -53
- package/src/adapters/generic-sql/migration/executor.test.ts +52 -0
- package/src/adapters/generic-sql/migration/executor.ts +47 -4
- package/src/adapters/generic-sql/migration/prepared-migrations.test.ts +238 -46
- package/src/adapters/generic-sql/migration/prepared-migrations.ts +21 -13
- package/src/adapters/generic-sql/migration/sql-generator.ts +145 -66
- package/src/adapters/generic-sql/query/create-sql-query-compiler.ts +11 -8
- package/src/adapters/generic-sql/query/cursor-utils.test.ts +272 -0
- package/src/adapters/generic-sql/query/cursor-utils.ts +42 -7
- package/src/adapters/generic-sql/query/db-now-sql.ts +49 -0
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.test.ts +171 -35
- package/src/adapters/generic-sql/query/generic-sql-uow-operation-compiler.ts +53 -40
- package/src/adapters/generic-sql/query/select-builder.test.ts +16 -11
- package/src/adapters/generic-sql/query/select-builder.ts +7 -3
- package/src/adapters/generic-sql/query/sql-query-compiler.test.ts +75 -6
- package/src/adapters/generic-sql/query/sql-query-compiler.ts +129 -24
- package/src/adapters/generic-sql/query/where-builder.test.ts +96 -20
- package/src/adapters/generic-sql/query/where-builder.ts +112 -41
- package/src/adapters/{kysely/kysely-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-migrations.test.ts} +11 -20
- package/src/adapters/generic-sql/sql-adapter-pglite-pagination.test.ts +851 -0
- package/src/adapters/{drizzle/drizzle-adapter-pglite.test.ts → generic-sql/sql-adapter-pglite-queries.test.ts} +18 -15
- package/src/adapters/generic-sql/{test/generic-drizzle-adapter-sqlite3.test.ts → sql-adapter-sqlite3-driver.test.ts} +282 -14
- package/src/adapters/{drizzle/drizzle-adapter-sqlite3.test.ts → generic-sql/sql-adapter-sqlite3-uow.test.ts} +129 -12
- package/src/adapters/{kysely/kysely-adapter-sqlocal.test.ts → generic-sql/sql-adapter-sqlocal.test.ts} +9 -7
- package/src/adapters/generic-sql/sqlite-storage.ts +20 -0
- package/src/adapters/generic-sql/uow-decoder.test.ts +5 -4
- package/src/adapters/generic-sql/uow-decoder.ts +23 -5
- package/src/adapters/generic-sql/uow-encoder.test.ts +36 -3
- package/src/adapters/generic-sql/uow-encoder.ts +48 -13
- package/src/adapters/in-memory/condition-evaluator.test.ts +194 -0
- package/src/adapters/in-memory/condition-evaluator.ts +280 -0
- package/src/adapters/in-memory/errors.ts +20 -0
- package/src/adapters/in-memory/in-memory-adapter.ts +388 -0
- package/src/adapters/in-memory/in-memory-uow.mutations.test.ts +344 -0
- package/src/adapters/in-memory/in-memory-uow.retrieval.test.ts +255 -0
- package/src/adapters/in-memory/in-memory-uow.ts +1724 -0
- package/src/adapters/in-memory/index.ts +3 -0
- package/src/adapters/in-memory/options.test.ts +42 -0
- package/src/adapters/in-memory/options.ts +91 -0
- package/src/adapters/in-memory/outbox.test.ts +361 -0
- package/src/adapters/in-memory/reference-resolution.test.ts +51 -0
- package/src/adapters/in-memory/reference-resolution.ts +67 -0
- package/src/adapters/in-memory/sorted-array-index.test.ts +124 -0
- package/src/adapters/in-memory/sorted-array-index.ts +228 -0
- package/src/adapters/in-memory/store.test.ts +69 -0
- package/src/adapters/in-memory/store.ts +145 -0
- package/src/adapters/in-memory/value-comparison.ts +53 -0
- package/src/adapters/in-memory/value-normalization.test.ts +58 -0
- package/src/adapters/prisma/prisma-adapter-sqlite3.test.ts +1207 -0
- package/src/adapters/shared/from-unit-of-work-compiler.ts +159 -47
- package/src/adapters/shared/uow-operation-compiler.ts +28 -18
- package/src/adapters/sql/index.ts +12 -0
- package/src/browser/mod.ts +64 -0
- package/src/client.ts +19 -0
- package/src/db-fragment-definition-builder.test.ts +845 -53
- package/src/db-fragment-definition-builder.ts +911 -95
- package/src/db-fragment-instantiator.test.ts +210 -94
- package/src/db-fragment-integration.test.ts +17 -12
- package/src/dispatchers/cloudflare-do/dispatcher.ts +204 -0
- package/src/dispatchers/cloudflare-do/index.test.ts +206 -0
- package/src/dispatchers/cloudflare-do/index.ts +63 -0
- package/src/dispatchers/node/dispatcher.ts +112 -0
- package/src/dispatchers/node/index.test.ts +120 -0
- package/src/dispatchers/node/index.ts +50 -0
- package/src/durable-hooks.test.ts +80 -0
- package/src/durable-hooks.ts +67 -0
- package/src/fragments/internal-fragment.routes.test.ts +570 -0
- package/src/fragments/internal-fragment.routes.ts +334 -0
- package/src/fragments/internal-fragment.schema.ts +95 -0
- package/src/fragments/internal-fragment.test.ts +505 -83
- package/src/fragments/internal-fragment.ts +453 -70
- package/src/hooks/durable-hooks-logger.ts +126 -0
- package/src/hooks/durable-hooks-processor.pglite.test.ts +87 -0
- package/src/hooks/durable-hooks-processor.test.ts +282 -0
- package/src/hooks/durable-hooks-processor.ts +173 -0
- package/src/hooks/durable-hooks-runtime.test.ts +65 -0
- package/src/hooks/durable-hooks-runtime.ts +81 -0
- package/src/hooks/hooks.test.ts +455 -34
- package/src/hooks/hooks.ts +501 -34
- package/src/id.test.ts +34 -0
- package/src/id.ts +1 -3
- package/src/internal/adapter-registry.test.ts +93 -0
- package/src/internal/adapter-registry.ts +239 -0
- package/src/internal/outbox-state.ts +43 -0
- package/src/migration-engine/auto-from-schema.test.ts +107 -14
- package/src/migration-engine/auto-from-schema.ts +365 -44
- package/src/migration-engine/create.test.ts +4 -3
- package/src/migration-engine/create.ts +1 -1
- package/src/migration-engine/generation-engine.test.ts +292 -110
- package/src/migration-engine/generation-engine.ts +117 -66
- package/src/migration-engine/shared.ts +14 -0
- package/src/mod.ts +95 -39
- package/src/naming/sql-naming.ts +181 -0
- package/src/outbox/outbox-builder.ts +241 -0
- package/src/outbox/outbox.test.ts +424 -0
- package/src/outbox/outbox.ts +139 -0
- package/src/query/column-defaults.ts +42 -4
- package/src/query/condition-builder.test.ts +18 -3
- package/src/query/condition-builder.ts +7 -0
- package/src/query/cursor-client.test.ts +70 -0
- package/src/query/cursor-client.ts +263 -0
- package/src/query/cursor.test.ts +119 -20
- package/src/query/cursor.ts +88 -27
- package/src/query/db-now.ts +73 -0
- package/src/query/orm/orm.ts +2 -2
- package/src/query/query-type.test.ts +4 -3
- package/src/query/serialize/create-sql-serializer.ts +10 -5
- package/src/query/serialize/dialect/mysql-serializer.ts +13 -5
- package/src/query/serialize/dialect/postgres-serializer.ts +35 -5
- package/src/query/serialize/dialect/sqlite-serializer.test.ts +90 -3
- package/src/query/serialize/dialect/sqlite-serializer.ts +108 -12
- package/src/query/serialize/sql-serializer.ts +4 -4
- package/src/query/simple-query-interface.ts +15 -4
- package/src/query/unit-of-work/execute-unit-of-work.test.ts +372 -10
- package/src/query/unit-of-work/execute-unit-of-work.ts +87 -27
- package/src/query/unit-of-work/retry-policy.test.ts +1 -0
- package/src/query/unit-of-work/tx-builder.test.ts +73 -1
- package/src/query/unit-of-work/unit-of-work-coordinator.test.ts +17 -16
- package/src/query/unit-of-work/unit-of-work-types.test.ts +42 -12
- package/src/query/unit-of-work/unit-of-work.test.ts +196 -39
- package/src/query/unit-of-work/unit-of-work.ts +309 -38
- package/src/query/value-decoding.test.ts +63 -4
- package/src/query/value-decoding.ts +32 -6
- package/src/query/value-encoding.test.ts +86 -2
- package/src/query/value-encoding.ts +56 -6
- package/src/schema/create.test.ts +293 -47
- package/src/schema/create.ts +406 -70
- package/src/schema/generate-id.test.ts +3 -2
- package/src/schema/generate-id.ts +2 -2
- package/src/schema/serialize.test.ts +18 -5
- package/src/schema/type-conversion/create-sql-type-mapper.ts +8 -3
- package/src/schema/type-conversion/dialect/sqlite.ts +18 -0
- package/src/schema/type-conversion/type-mapping.test.ts +26 -1
- package/src/schema/validator.test.ts +199 -0
- package/src/schema/validator.ts +232 -0
- package/src/{adapters/drizzle/generate.test.ts → schema-output/drizzle.test.ts} +232 -129
- package/src/{adapters/drizzle/generate.ts → schema-output/drizzle.ts} +155 -99
- package/src/schema-output/prisma.test.ts +694 -0
- package/src/schema-output/prisma.ts +593 -0
- package/src/sql-driver/better-sqlite3.test.ts +5 -3
- package/src/sql-driver/dialects/durable-object-dialect.ts +3 -8
- package/src/sql-driver/query-executor/default-query-executor.ts +1 -1
- package/src/sql-driver/query-executor/query-executor-base.ts +1 -1
- package/src/sql-driver/query-executor/query-executor.ts +1 -1
- package/src/sql-driver/sql-driver-adapter.ts +2 -2
- package/src/sql-driver/sql.ts +2 -1
- package/src/sql-driver/sqlocal.test.ts +4 -2
- package/src/sync/commands.test.ts +39 -0
- package/src/sync/commands.ts +51 -0
- package/src/sync/conflict-checker.test.ts +450 -0
- package/src/sync/conflict-checker.ts +248 -0
- package/src/sync/index.ts +14 -0
- package/src/sync/plan.ts +9 -0
- package/src/sync/read-tracking.test.ts +177 -0
- package/src/sync/read-tracking.ts +287 -0
- package/src/sync/submit.test.ts +205 -0
- package/src/sync/submit.ts +328 -0
- package/src/sync/types.ts +80 -0
- package/src/util/default-database-adapter.ts +119 -0
- package/src/with-database.ts +20 -31
- package/tsconfig.json +1 -1
- package/tsdown.config.ts +38 -24
- package/vitest.config.ts +1 -0
- package/dist/adapters/drizzle/drizzle-adapter.d.ts +0 -20
- package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +0 -1
- package/dist/adapters/drizzle/drizzle-adapter.js +0 -27
- package/dist/adapters/drizzle/drizzle-adapter.js.map +0 -1
- package/dist/adapters/drizzle/generate.d.ts +0 -30
- package/dist/adapters/drizzle/generate.d.ts.map +0 -1
- package/dist/adapters/drizzle/generate.js.map +0 -1
- package/dist/adapters/kysely/kysely-adapter.d.ts +0 -19
- package/dist/adapters/kysely/kysely-adapter.d.ts.map +0 -1
- package/dist/adapters/kysely/kysely-adapter.js +0 -17
- package/dist/adapters/kysely/kysely-adapter.js.map +0 -1
- package/dist/adapters/shared/table-name-mapper.d.ts +0 -12
- package/dist/adapters/shared/table-name-mapper.d.ts.map +0 -1
- package/dist/adapters/shared/table-name-mapper.js +0 -43
- package/dist/adapters/shared/table-name-mapper.js.map +0 -1
- package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js +0 -165
- package/dist/node_modules/.pnpm/rou3@0.7.10/node_modules/rou3/dist/index.js.map +0 -1
- package/dist/packages/fragno/dist/api/bind-services.js +0 -20
- package/dist/packages/fragno/dist/api/bind-services.js.map +0 -1
- package/dist/packages/fragno/dist/api/error.js +0 -48
- package/dist/packages/fragno/dist/api/error.js.map +0 -1
- package/dist/packages/fragno/dist/api/fragment-definition-builder.js +0 -320
- package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +0 -1
- package/dist/packages/fragno/dist/api/fragment-instantiator.js +0 -525
- package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +0 -1
- package/dist/packages/fragno/dist/api/fragno-response.js +0 -73
- package/dist/packages/fragno/dist/api/fragno-response.js.map +0 -1
- package/dist/packages/fragno/dist/api/internal/response-stream.js +0 -81
- package/dist/packages/fragno/dist/api/internal/response-stream.js.map +0 -1
- package/dist/packages/fragno/dist/api/internal/route.js +0 -10
- package/dist/packages/fragno/dist/api/internal/route.js.map +0 -1
- package/dist/packages/fragno/dist/api/mutable-request-state.js +0 -97
- package/dist/packages/fragno/dist/api/mutable-request-state.js.map +0 -1
- package/dist/packages/fragno/dist/api/request-context-storage.js +0 -43
- package/dist/packages/fragno/dist/api/request-context-storage.js.map +0 -1
- package/dist/packages/fragno/dist/api/request-input-context.js +0 -118
- package/dist/packages/fragno/dist/api/request-input-context.js.map +0 -1
- package/dist/packages/fragno/dist/api/request-middleware.js +0 -83
- package/dist/packages/fragno/dist/api/request-middleware.js.map +0 -1
- package/dist/packages/fragno/dist/api/request-output-context.js +0 -119
- package/dist/packages/fragno/dist/api/request-output-context.js.map +0 -1
- package/dist/packages/fragno/dist/api/route.js +0 -17
- package/dist/packages/fragno/dist/api/route.js.map +0 -1
- package/dist/packages/fragno/dist/internal/symbols.js +0 -10
- package/dist/packages/fragno/dist/internal/symbols.js.map +0 -1
- package/dist/schema-generator/schema-generator.d.ts +0 -15
- package/dist/schema-generator/schema-generator.d.ts.map +0 -1
- package/src/adapters/drizzle/drizzle-adapter.ts +0 -39
- package/src/adapters/kysely/kysely-adapter.ts +0 -27
- package/src/adapters/shared/table-name-mapper.ts +0 -50
- package/src/schema-generator/schema-generator.ts +0 -12
|
@@ -1,26 +1,32 @@
|
|
|
1
|
-
import { describe, it, expect, expectTypeOf } from "vitest";
|
|
1
|
+
import { describe, it, expect, expectTypeOf, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { InMemoryAdapter } from "../../adapters/in-memory/in-memory-adapter";
|
|
4
|
+
import type { InternalFragmentInstance } from "../../fragments/internal-fragment";
|
|
5
|
+
import { internalSchema } from "../../fragments/internal-fragment.schema";
|
|
6
|
+
import { prepareHookMutations } from "../../hooks/hooks";
|
|
2
7
|
import { schema, idColumn, FragnoId } from "../../schema/create";
|
|
3
|
-
import {
|
|
4
|
-
createUnitOfWork,
|
|
5
|
-
type IUnitOfWork,
|
|
6
|
-
type UOWCompiler,
|
|
7
|
-
type UOWDecoder,
|
|
8
|
-
type UOWExecutor,
|
|
9
|
-
} from "./unit-of-work";
|
|
10
8
|
import {
|
|
11
9
|
createServiceTxBuilder,
|
|
12
10
|
createHandlerTxBuilder,
|
|
13
11
|
isTxResult,
|
|
12
|
+
serviceCalls,
|
|
14
13
|
ConcurrencyConflictError,
|
|
15
14
|
} from "./execute-unit-of-work";
|
|
15
|
+
import type { AwaitedPromisesInObject, TxResult } from "./execute-unit-of-work";
|
|
16
16
|
import {
|
|
17
17
|
ExponentialBackoffRetryPolicy,
|
|
18
18
|
LinearBackoffRetryPolicy,
|
|
19
19
|
NoRetryPolicy,
|
|
20
20
|
} from "./retry-policy";
|
|
21
|
-
import
|
|
21
|
+
import {
|
|
22
|
+
createUnitOfWork,
|
|
23
|
+
type IUnitOfWork,
|
|
24
|
+
type UOWCompiler,
|
|
25
|
+
type UOWDecoder,
|
|
26
|
+
type UOWExecutor,
|
|
27
|
+
} from "./unit-of-work";
|
|
22
28
|
|
|
23
|
-
const testSchema = schema((s) =>
|
|
29
|
+
const testSchema = schema("test", (s) =>
|
|
24
30
|
s.addTable("users", (t) =>
|
|
25
31
|
t
|
|
26
32
|
.addColumn("id", idColumn())
|
|
@@ -31,6 +37,42 @@ const testSchema = schema((s) =>
|
|
|
31
37
|
),
|
|
32
38
|
);
|
|
33
39
|
|
|
40
|
+
function setupCrossSchemaHookTest() {
|
|
41
|
+
const adapter = new InMemoryAdapter();
|
|
42
|
+
const schemaA = schema("alpha", (s) =>
|
|
43
|
+
s.addTable("items", (t) => t.addColumn("id", idColumn()).addColumn("label", "string")),
|
|
44
|
+
);
|
|
45
|
+
const schemaB = schema("beta", (s) =>
|
|
46
|
+
s.addTable("items", (t) => t.addColumn("id", idColumn()).addColumn("label", "string")),
|
|
47
|
+
);
|
|
48
|
+
const namespaceA = "alpha";
|
|
49
|
+
const namespaceB = "beta";
|
|
50
|
+
|
|
51
|
+
const queryA = adapter.createQueryEngine(schemaA, namespaceA);
|
|
52
|
+
const queryB = adapter.createQueryEngine(schemaB, namespaceB);
|
|
53
|
+
const internalQuery = adapter.createQueryEngine(internalSchema, null);
|
|
54
|
+
|
|
55
|
+
const internalFragment = {
|
|
56
|
+
$internal: {
|
|
57
|
+
deps: {
|
|
58
|
+
schema: internalSchema,
|
|
59
|
+
namespace: null,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
} as InternalFragmentInstance;
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
schemaA,
|
|
66
|
+
schemaB,
|
|
67
|
+
namespaceA,
|
|
68
|
+
namespaceB,
|
|
69
|
+
queryA,
|
|
70
|
+
queryB,
|
|
71
|
+
internalQuery,
|
|
72
|
+
internalFragment,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
34
76
|
describe("AwaitedPromisesInObject type tests", () => {
|
|
35
77
|
it("should unwrap promises in objects", () => {
|
|
36
78
|
type Input = { a: Promise<string>; b: number };
|
|
@@ -390,6 +432,36 @@ describe("Unified Tx API", () => {
|
|
|
390
432
|
expect(users[1].name).toBe("Bob");
|
|
391
433
|
});
|
|
392
434
|
|
|
435
|
+
it("should call onAfterRetrieve with full results", async () => {
|
|
436
|
+
const compiler = createMockCompiler();
|
|
437
|
+
const mockUsers = [
|
|
438
|
+
{
|
|
439
|
+
id: FragnoId.fromExternal("1", 1),
|
|
440
|
+
email: "alice@example.com",
|
|
441
|
+
name: "Alice",
|
|
442
|
+
balance: 100,
|
|
443
|
+
},
|
|
444
|
+
];
|
|
445
|
+
const executor: UOWExecutor<unknown, unknown> = {
|
|
446
|
+
executeRetrievalPhase: async () => [mockUsers],
|
|
447
|
+
executeMutationPhase: async () => ({ success: true, createdInternalIds: [] }),
|
|
448
|
+
};
|
|
449
|
+
const decoder = createMockDecoder();
|
|
450
|
+
const onAfterRetrieve = vi.fn();
|
|
451
|
+
|
|
452
|
+
await createHandlerTxBuilder({
|
|
453
|
+
createUnitOfWork: () => createUnitOfWork(compiler, executor, decoder),
|
|
454
|
+
onAfterRetrieve,
|
|
455
|
+
})
|
|
456
|
+
.retrieve(({ forSchema }) =>
|
|
457
|
+
forSchema(testSchema).find("users", (b) => b.whereIndex("idx_email")),
|
|
458
|
+
)
|
|
459
|
+
.execute();
|
|
460
|
+
|
|
461
|
+
expect(onAfterRetrieve).toHaveBeenCalledOnce();
|
|
462
|
+
expect(onAfterRetrieve.mock.calls[0]?.[1]).toEqual([mockUsers]);
|
|
463
|
+
});
|
|
464
|
+
|
|
393
465
|
it("should execute a simple mutate-only transaction", async () => {
|
|
394
466
|
const compiler = createMockCompiler();
|
|
395
467
|
const executor: UOWExecutor<unknown, unknown> = {
|
|
@@ -414,6 +486,26 @@ describe("Unified Tx API", () => {
|
|
|
414
486
|
expect(result.userId).toBeInstanceOf(FragnoId);
|
|
415
487
|
});
|
|
416
488
|
|
|
489
|
+
it("should throw when retry policy is provided without retrieve operations", async () => {
|
|
490
|
+
const compiler = createMockCompiler();
|
|
491
|
+
const executor: UOWExecutor<unknown, unknown> = {
|
|
492
|
+
executeRetrievalPhase: async () => [],
|
|
493
|
+
executeMutationPhase: async () => ({ success: false }),
|
|
494
|
+
};
|
|
495
|
+
const decoder = createMockDecoder();
|
|
496
|
+
|
|
497
|
+
await expect(
|
|
498
|
+
createHandlerTxBuilder({
|
|
499
|
+
createUnitOfWork: () => createUnitOfWork(compiler, executor, decoder),
|
|
500
|
+
retryPolicy: new NoRetryPolicy(),
|
|
501
|
+
})
|
|
502
|
+
.mutate(() => ({ done: true }))
|
|
503
|
+
.execute(),
|
|
504
|
+
).rejects.toThrow(
|
|
505
|
+
"Retry policy is only supported when the transaction includes retrieve operations.",
|
|
506
|
+
);
|
|
507
|
+
});
|
|
508
|
+
|
|
417
509
|
it("should execute a transaction with serviceCalls as retrieve source", async () => {
|
|
418
510
|
const compiler = createMockCompiler();
|
|
419
511
|
const mockUser = {
|
|
@@ -753,6 +845,72 @@ describe("Unified Tx API", () => {
|
|
|
753
845
|
expect(result.finalDepUserId).toBeInstanceOf(FragnoId);
|
|
754
846
|
});
|
|
755
847
|
|
|
848
|
+
it("should preserve tuple inference for dynamic serviceCalls using helper", async () => {
|
|
849
|
+
const compiler = createMockCompiler();
|
|
850
|
+
const executor: UOWExecutor<unknown, unknown> = {
|
|
851
|
+
executeRetrievalPhase: async () => [],
|
|
852
|
+
executeMutationPhase: async () => ({ success: true, createdInternalIds: [BigInt(1)] }),
|
|
853
|
+
};
|
|
854
|
+
const decoder = createMockDecoder();
|
|
855
|
+
|
|
856
|
+
let currentUow: IUnitOfWork | null = null;
|
|
857
|
+
|
|
858
|
+
type UserData = { id: FragnoId; email: string };
|
|
859
|
+
type Stats = { count: number };
|
|
860
|
+
type HistoryEntry = { page: number };
|
|
861
|
+
|
|
862
|
+
const getUser = () =>
|
|
863
|
+
createServiceTxBuilder(testSchema, currentUow!)
|
|
864
|
+
.mutate(({ uow }): UserData => {
|
|
865
|
+
const userId = uow.create("users", {
|
|
866
|
+
email: "user@example.com",
|
|
867
|
+
name: "User",
|
|
868
|
+
balance: 0,
|
|
869
|
+
});
|
|
870
|
+
return { id: userId, email: "user@example.com" };
|
|
871
|
+
})
|
|
872
|
+
.build();
|
|
873
|
+
|
|
874
|
+
const getStats = () =>
|
|
875
|
+
createServiceTxBuilder(testSchema, currentUow!)
|
|
876
|
+
.mutate((): Stats => ({ count: 42 }))
|
|
877
|
+
.build();
|
|
878
|
+
|
|
879
|
+
const listHistory = (page: number) =>
|
|
880
|
+
createServiceTxBuilder(testSchema, currentUow!)
|
|
881
|
+
.mutate((): HistoryEntry => ({ page }))
|
|
882
|
+
.build();
|
|
883
|
+
|
|
884
|
+
const result = await createHandlerTxBuilder({
|
|
885
|
+
createUnitOfWork: () => {
|
|
886
|
+
currentUow = createUnitOfWork(compiler, executor, decoder);
|
|
887
|
+
return currentUow;
|
|
888
|
+
},
|
|
889
|
+
})
|
|
890
|
+
.withServiceCalls(() => {
|
|
891
|
+
const historyCalls = Array.from({ length: 2 }, (_, idx) => listHistory(idx + 1));
|
|
892
|
+
return serviceCalls(getUser(), getStats(), ...historyCalls);
|
|
893
|
+
})
|
|
894
|
+
.mutate(({ serviceIntermediateResult }) => {
|
|
895
|
+
const [user, stats, ...history] = serviceIntermediateResult;
|
|
896
|
+
|
|
897
|
+
expectTypeOf(user).toEqualTypeOf<UserData>();
|
|
898
|
+
expectTypeOf(stats).toEqualTypeOf<Stats>();
|
|
899
|
+
expectTypeOf(history).items.toEqualTypeOf<HistoryEntry>();
|
|
900
|
+
|
|
901
|
+
return {
|
|
902
|
+
userId: user.id,
|
|
903
|
+
count: stats.count,
|
|
904
|
+
pages: history.map((entry) => entry.page),
|
|
905
|
+
};
|
|
906
|
+
})
|
|
907
|
+
.execute();
|
|
908
|
+
|
|
909
|
+
expect(result.count).toBe(42);
|
|
910
|
+
expect(result.pages).toEqual([1, 2]);
|
|
911
|
+
expect(result.userId).toBeInstanceOf(FragnoId);
|
|
912
|
+
});
|
|
913
|
+
|
|
756
914
|
it("should retry on concurrency conflict", async () => {
|
|
757
915
|
const compiler = createMockCompiler();
|
|
758
916
|
let mutationAttempts = 0;
|
|
@@ -772,6 +930,7 @@ describe("Unified Tx API", () => {
|
|
|
772
930
|
createUnitOfWork: () => createUnitOfWork(compiler, executor, decoder),
|
|
773
931
|
retryPolicy: new ExponentialBackoffRetryPolicy({ maxRetries: 5, initialDelayMs: 1 }),
|
|
774
932
|
})
|
|
933
|
+
.retrieve(({ forSchema }) => forSchema(testSchema).find("users"))
|
|
775
934
|
.mutate(({ forSchema }) => {
|
|
776
935
|
forSchema(testSchema).create("users", {
|
|
777
936
|
email: "test@example.com",
|
|
@@ -801,6 +960,7 @@ describe("Unified Tx API", () => {
|
|
|
801
960
|
createUnitOfWork: () => createUnitOfWork(compiler, executor, decoder),
|
|
802
961
|
retryPolicy: new NoRetryPolicy(),
|
|
803
962
|
})
|
|
963
|
+
.retrieve(({ forSchema }) => forSchema(testSchema).find("users"))
|
|
804
964
|
.mutate(() => ({ done: true }))
|
|
805
965
|
.execute(),
|
|
806
966
|
).rejects.toThrow(ConcurrencyConflictError);
|
|
@@ -850,6 +1010,7 @@ describe("Unified Tx API", () => {
|
|
|
850
1010
|
},
|
|
851
1011
|
retryPolicy: new LinearBackoffRetryPolicy({ maxRetries: 3, delayMs: 1 }),
|
|
852
1012
|
})
|
|
1013
|
+
.retrieve(({ forSchema }) => forSchema(testSchema).find("users"))
|
|
853
1014
|
.mutate(({ forSchema }) => {
|
|
854
1015
|
forSchema(testSchema).create("users", {
|
|
855
1016
|
email: "test@example.com",
|
|
@@ -882,11 +1043,94 @@ describe("Unified Tx API", () => {
|
|
|
882
1043
|
retryPolicy: new LinearBackoffRetryPolicy({ maxRetries: 5, delayMs: 100 }),
|
|
883
1044
|
signal: controller.signal,
|
|
884
1045
|
})
|
|
1046
|
+
.retrieve(({ forSchema }) => forSchema(testSchema).find("users"))
|
|
885
1047
|
.mutate(() => ({ done: true }))
|
|
886
1048
|
.execute(),
|
|
887
1049
|
).rejects.toThrow("Transaction execution aborted");
|
|
888
1050
|
});
|
|
889
1051
|
|
|
1052
|
+
it("should propagate error when mutate callback rejects a duplicate via retrieve guard", async () => {
|
|
1053
|
+
const compiler = createMockCompiler();
|
|
1054
|
+
const existingUser = {
|
|
1055
|
+
id: FragnoId.fromExternal("existing-1", 1),
|
|
1056
|
+
email: "alice@example.com",
|
|
1057
|
+
name: "Alice",
|
|
1058
|
+
balance: 100,
|
|
1059
|
+
};
|
|
1060
|
+
const executor: UOWExecutor<unknown, unknown> = {
|
|
1061
|
+
executeRetrievalPhase: async () => [[existingUser]],
|
|
1062
|
+
executeMutationPhase: async () => ({ success: true, createdInternalIds: [] }),
|
|
1063
|
+
};
|
|
1064
|
+
const decoder = createMockDecoder();
|
|
1065
|
+
|
|
1066
|
+
let currentUow: IUnitOfWork | null = null;
|
|
1067
|
+
|
|
1068
|
+
const createIfNotExists = (email: string) => {
|
|
1069
|
+
return createServiceTxBuilder(testSchema, currentUow!)
|
|
1070
|
+
.retrieve((uow) =>
|
|
1071
|
+
uow.find("users", (b) => b.whereIndex("idx_email", (eb) => eb("email", "=", email))),
|
|
1072
|
+
)
|
|
1073
|
+
.mutate(({ uow, retrieveResult: [users] }) => {
|
|
1074
|
+
if (users.length > 0) {
|
|
1075
|
+
throw new Error("ALREADY_EXISTS");
|
|
1076
|
+
}
|
|
1077
|
+
const id = uow.create("users", { email, name: "New", balance: 0 });
|
|
1078
|
+
return { id };
|
|
1079
|
+
})
|
|
1080
|
+
.build();
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
await expect(
|
|
1084
|
+
createHandlerTxBuilder({
|
|
1085
|
+
createUnitOfWork: () => {
|
|
1086
|
+
currentUow = createUnitOfWork(compiler, executor, decoder);
|
|
1087
|
+
return currentUow;
|
|
1088
|
+
},
|
|
1089
|
+
})
|
|
1090
|
+
.withServiceCalls(() => [createIfNotExists("alice@example.com")])
|
|
1091
|
+
.transform(({ serviceResult: [result] }) => result)
|
|
1092
|
+
.execute(),
|
|
1093
|
+
).rejects.toThrow("ALREADY_EXISTS");
|
|
1094
|
+
});
|
|
1095
|
+
|
|
1096
|
+
it("should succeed when retrieve guard finds no existing record", async () => {
|
|
1097
|
+
const compiler = createMockCompiler();
|
|
1098
|
+
const executor: UOWExecutor<unknown, unknown> = {
|
|
1099
|
+
executeRetrievalPhase: async () => [[]],
|
|
1100
|
+
executeMutationPhase: async () => ({ success: true, createdInternalIds: [BigInt(1)] }),
|
|
1101
|
+
};
|
|
1102
|
+
const decoder = createMockDecoder();
|
|
1103
|
+
|
|
1104
|
+
let currentUow: IUnitOfWork | null = null;
|
|
1105
|
+
|
|
1106
|
+
const createIfNotExists = (email: string) => {
|
|
1107
|
+
return createServiceTxBuilder(testSchema, currentUow!)
|
|
1108
|
+
.retrieve((uow) =>
|
|
1109
|
+
uow.find("users", (b) => b.whereIndex("idx_email", (eb) => eb("email", "=", email))),
|
|
1110
|
+
)
|
|
1111
|
+
.mutate(({ uow, retrieveResult: [users] }) => {
|
|
1112
|
+
if (users.length > 0) {
|
|
1113
|
+
throw new Error("ALREADY_EXISTS");
|
|
1114
|
+
}
|
|
1115
|
+
const id = uow.create("users", { email, name: "New", balance: 0 });
|
|
1116
|
+
return { id };
|
|
1117
|
+
})
|
|
1118
|
+
.build();
|
|
1119
|
+
};
|
|
1120
|
+
|
|
1121
|
+
const result = await createHandlerTxBuilder({
|
|
1122
|
+
createUnitOfWork: () => {
|
|
1123
|
+
currentUow = createUnitOfWork(compiler, executor, decoder);
|
|
1124
|
+
return currentUow;
|
|
1125
|
+
},
|
|
1126
|
+
})
|
|
1127
|
+
.withServiceCalls(() => [createIfNotExists("new@example.com")])
|
|
1128
|
+
.transform(({ serviceResult: [result] }) => result)
|
|
1129
|
+
.execute();
|
|
1130
|
+
|
|
1131
|
+
expect(result.id).toBeInstanceOf(FragnoId);
|
|
1132
|
+
});
|
|
1133
|
+
|
|
890
1134
|
it("should pass serviceResult to transform callback with final results", async () => {
|
|
891
1135
|
const compiler = createMockCompiler();
|
|
892
1136
|
const mockUser = {
|
|
@@ -1523,6 +1767,7 @@ describe("Unified Tx API", () => {
|
|
|
1523
1767
|
await createHandlerTxBuilder({
|
|
1524
1768
|
createUnitOfWork: () => {
|
|
1525
1769
|
currentUow = createUnitOfWork(compiler, executor, decoder);
|
|
1770
|
+
currentUow.registerSchema(testSchema, "test");
|
|
1526
1771
|
return currentUow;
|
|
1527
1772
|
},
|
|
1528
1773
|
})
|
|
@@ -1592,6 +1837,7 @@ describe("Unified Tx API", () => {
|
|
|
1592
1837
|
await createHandlerTxBuilder({
|
|
1593
1838
|
createUnitOfWork: () => {
|
|
1594
1839
|
currentUow = createUnitOfWork(compiler, executor, decoder);
|
|
1840
|
+
currentUow.registerSchema(testSchema, "test");
|
|
1595
1841
|
return currentUow;
|
|
1596
1842
|
},
|
|
1597
1843
|
})
|
|
@@ -1607,6 +1853,122 @@ describe("Unified Tx API", () => {
|
|
|
1607
1853
|
payload: { userId: expect.any(String) },
|
|
1608
1854
|
});
|
|
1609
1855
|
});
|
|
1856
|
+
|
|
1857
|
+
it("should create hook records when handler uses schema A and service uses schema B", async () => {
|
|
1858
|
+
const { schemaA, schemaB, namespaceA, namespaceB, queryA, internalQuery, internalFragment } =
|
|
1859
|
+
setupCrossSchemaHookTest();
|
|
1860
|
+
|
|
1861
|
+
type HooksA = {
|
|
1862
|
+
onAlpha: (payload: { value: string }) => void;
|
|
1863
|
+
};
|
|
1864
|
+
type HooksB = {
|
|
1865
|
+
onBeta: (payload: { value: string }) => void;
|
|
1866
|
+
};
|
|
1867
|
+
|
|
1868
|
+
const hooksA: HooksA = {
|
|
1869
|
+
onAlpha: (_payload) => {},
|
|
1870
|
+
};
|
|
1871
|
+
const hooksB: HooksB = {
|
|
1872
|
+
onBeta: (_payload) => {},
|
|
1873
|
+
};
|
|
1874
|
+
|
|
1875
|
+
let currentUow: IUnitOfWork | null = null;
|
|
1876
|
+
|
|
1877
|
+
const serviceInSchemaB = (value: string) =>
|
|
1878
|
+
createServiceTxBuilder(schemaB, currentUow!, hooksB)
|
|
1879
|
+
.mutate(({ uow }) => {
|
|
1880
|
+
uow.create("items", { label: value });
|
|
1881
|
+
uow.triggerHook("onBeta", { value });
|
|
1882
|
+
})
|
|
1883
|
+
.build();
|
|
1884
|
+
|
|
1885
|
+
await createHandlerTxBuilder({
|
|
1886
|
+
createUnitOfWork: () => {
|
|
1887
|
+
currentUow = queryA.createBaseUnitOfWork();
|
|
1888
|
+
currentUow.registerSchema(schemaA, namespaceA);
|
|
1889
|
+
currentUow.registerSchema(schemaB, namespaceB);
|
|
1890
|
+
currentUow.registerSchema(internalSchema, null);
|
|
1891
|
+
return currentUow;
|
|
1892
|
+
},
|
|
1893
|
+
onBeforeMutate: (uow) => {
|
|
1894
|
+
prepareHookMutations(uow, internalFragment);
|
|
1895
|
+
},
|
|
1896
|
+
})
|
|
1897
|
+
.mutate(({ forSchema }) => {
|
|
1898
|
+
const uow = forSchema(schemaA, hooksA);
|
|
1899
|
+
uow.create("items", { label: "alpha" });
|
|
1900
|
+
uow.triggerHook("onAlpha", { value: "alpha" });
|
|
1901
|
+
})
|
|
1902
|
+
.withServiceCalls(() => [serviceInSchemaB("beta")] as const)
|
|
1903
|
+
.execute();
|
|
1904
|
+
|
|
1905
|
+
const hooks = await internalQuery.find("fragno_hooks");
|
|
1906
|
+
expect(hooks).toHaveLength(2);
|
|
1907
|
+
expect(hooks).toEqual(
|
|
1908
|
+
expect.arrayContaining([
|
|
1909
|
+
expect.objectContaining({ hookName: "onAlpha", namespace: namespaceA }),
|
|
1910
|
+
expect.objectContaining({ hookName: "onBeta", namespace: namespaceB }),
|
|
1911
|
+
]),
|
|
1912
|
+
);
|
|
1913
|
+
});
|
|
1914
|
+
|
|
1915
|
+
it("should create hook records when handler uses schema B and service uses schema A", async () => {
|
|
1916
|
+
const { schemaA, schemaB, namespaceA, namespaceB, queryB, internalQuery, internalFragment } =
|
|
1917
|
+
setupCrossSchemaHookTest();
|
|
1918
|
+
|
|
1919
|
+
type HooksA = {
|
|
1920
|
+
onAlpha: (payload: { value: string }) => void;
|
|
1921
|
+
};
|
|
1922
|
+
type HooksB = {
|
|
1923
|
+
onBeta: (payload: { value: string }) => void;
|
|
1924
|
+
};
|
|
1925
|
+
|
|
1926
|
+
const hooksA: HooksA = {
|
|
1927
|
+
onAlpha: (_payload) => {},
|
|
1928
|
+
};
|
|
1929
|
+
const hooksB: HooksB = {
|
|
1930
|
+
onBeta: (_payload) => {},
|
|
1931
|
+
};
|
|
1932
|
+
|
|
1933
|
+
let currentUow: IUnitOfWork | null = null;
|
|
1934
|
+
|
|
1935
|
+
const serviceInSchemaA = (value: string) =>
|
|
1936
|
+
createServiceTxBuilder(schemaA, currentUow!, hooksA)
|
|
1937
|
+
.mutate(({ uow }) => {
|
|
1938
|
+
uow.create("items", { label: value });
|
|
1939
|
+
uow.triggerHook("onAlpha", { value });
|
|
1940
|
+
})
|
|
1941
|
+
.build();
|
|
1942
|
+
|
|
1943
|
+
await createHandlerTxBuilder({
|
|
1944
|
+
createUnitOfWork: () => {
|
|
1945
|
+
currentUow = queryB.createBaseUnitOfWork();
|
|
1946
|
+
currentUow.registerSchema(schemaA, namespaceA);
|
|
1947
|
+
currentUow.registerSchema(schemaB, namespaceB);
|
|
1948
|
+
currentUow.registerSchema(internalSchema, null);
|
|
1949
|
+
return currentUow;
|
|
1950
|
+
},
|
|
1951
|
+
onBeforeMutate: (uow) => {
|
|
1952
|
+
prepareHookMutations(uow, internalFragment);
|
|
1953
|
+
},
|
|
1954
|
+
})
|
|
1955
|
+
.mutate(({ forSchema }) => {
|
|
1956
|
+
const uow = forSchema(schemaB, hooksB);
|
|
1957
|
+
uow.create("items", { label: "beta" });
|
|
1958
|
+
uow.triggerHook("onBeta", { value: "beta" });
|
|
1959
|
+
})
|
|
1960
|
+
.withServiceCalls(() => [serviceInSchemaA("alpha")] as const)
|
|
1961
|
+
.execute();
|
|
1962
|
+
|
|
1963
|
+
const hooks = await internalQuery.find("fragno_hooks");
|
|
1964
|
+
expect(hooks).toHaveLength(2);
|
|
1965
|
+
expect(hooks).toEqual(
|
|
1966
|
+
expect.arrayContaining([
|
|
1967
|
+
expect.objectContaining({ hookName: "onAlpha", namespace: namespaceA }),
|
|
1968
|
+
expect.objectContaining({ hookName: "onBeta", namespace: namespaceB }),
|
|
1969
|
+
]),
|
|
1970
|
+
);
|
|
1971
|
+
});
|
|
1610
1972
|
});
|
|
1611
1973
|
|
|
1612
1974
|
describe("error handling in createServiceTx", () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import type { HooksMap } from "../../hooks/hooks";
|
|
1
2
|
import type { AnySchema } from "../../schema/create";
|
|
3
|
+
import { ExponentialBackoffRetryPolicy, NoRetryPolicy, type RetryPolicy } from "./retry-policy";
|
|
2
4
|
import type { TypedUnitOfWork, IUnitOfWork } from "./unit-of-work";
|
|
3
|
-
import type { HooksMap } from "../../hooks/hooks";
|
|
4
|
-
import { ExponentialBackoffRetryPolicy, type RetryPolicy } from "./retry-policy";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Symbol to identify TxResult objects
|
|
@@ -58,6 +58,26 @@ export type ExtractServiceFinalResults<T extends readonly unknown[]> = {
|
|
|
58
58
|
[K in keyof T]: ExtractTxFinalResult<T[K]>;
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Helper to preserve tuple inference for service calls, especially with spreads.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* const historyCalls = Array.from({ length: 3 }, () => svc.listHistory(...));
|
|
67
|
+
* return serviceCalls(
|
|
68
|
+
* svc.getInstanceStatus(...),
|
|
69
|
+
* svc.getInstanceRunNumber(...),
|
|
70
|
+
* ...historyCalls,
|
|
71
|
+
* );
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
75
|
+
export function serviceCalls<const T extends readonly (TxResult<any, any> | undefined)[]>(
|
|
76
|
+
...calls: T
|
|
77
|
+
): T {
|
|
78
|
+
return calls;
|
|
79
|
+
}
|
|
80
|
+
|
|
61
81
|
/**
|
|
62
82
|
* Context passed to mutate callback for service methods
|
|
63
83
|
*/
|
|
@@ -491,6 +511,12 @@ export interface ExecuteTxOptions {
|
|
|
491
511
|
*/
|
|
492
512
|
signal?: AbortSignal;
|
|
493
513
|
|
|
514
|
+
/**
|
|
515
|
+
* Callback invoked after retrieval phase completes.
|
|
516
|
+
* Use this to inspect retrieval operations and results (e.g., read tracking).
|
|
517
|
+
*/
|
|
518
|
+
onAfterRetrieve?: (uow: IUnitOfWork, results: unknown[]) => void | Promise<void>;
|
|
519
|
+
|
|
494
520
|
/**
|
|
495
521
|
* Callback invoked before mutations are executed.
|
|
496
522
|
* Use this to add additional mutation operations (e.g., hook event records).
|
|
@@ -502,6 +528,11 @@ export interface ExecuteTxOptions {
|
|
|
502
528
|
* Use this for post-mutation processing like hook execution.
|
|
503
529
|
*/
|
|
504
530
|
onAfterMutate?: (uow: IUnitOfWork) => Promise<void>;
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Plan mode suppresses hook execution while still running serviceTx logic.
|
|
534
|
+
*/
|
|
535
|
+
planMode?: boolean;
|
|
505
536
|
}
|
|
506
537
|
|
|
507
538
|
/**
|
|
@@ -724,13 +755,6 @@ async function executeTx(
|
|
|
724
755
|
type TServiceCalls = readonly (TxResult<any, any> | undefined)[];
|
|
725
756
|
type TMutateResult = unknown;
|
|
726
757
|
type THooks = HooksMap;
|
|
727
|
-
const retryPolicy =
|
|
728
|
-
options.retryPolicy ??
|
|
729
|
-
new ExponentialBackoffRetryPolicy({
|
|
730
|
-
maxRetries: 5,
|
|
731
|
-
initialDelayMs: 10,
|
|
732
|
-
maxDelayMs: 100,
|
|
733
|
-
});
|
|
734
758
|
const signal = options.signal;
|
|
735
759
|
let attempt = 0;
|
|
736
760
|
|
|
@@ -740,9 +764,15 @@ async function executeTx(
|
|
|
740
764
|
throw new Error("Transaction execution aborted");
|
|
741
765
|
}
|
|
742
766
|
|
|
767
|
+
let retryPolicy: RetryPolicy | undefined;
|
|
768
|
+
|
|
743
769
|
try {
|
|
744
770
|
// Create a fresh UOW for this attempt
|
|
745
771
|
const baseUow = options.createUnitOfWork();
|
|
772
|
+
if (options.onAfterRetrieve) {
|
|
773
|
+
const readTrackingUow = baseUow as { enableReadTracking?: () => void };
|
|
774
|
+
readTrackingUow.enableReadTracking?.();
|
|
775
|
+
}
|
|
746
776
|
|
|
747
777
|
// Create handler context
|
|
748
778
|
const context: HandlerTxContext<THooks> = {
|
|
@@ -764,7 +794,28 @@ async function executeTx(
|
|
|
764
794
|
|
|
765
795
|
const allServiceCallTxResults = serviceCalls ? collectAllTxResults([...serviceCalls]) : [];
|
|
766
796
|
|
|
767
|
-
|
|
797
|
+
const hasRetrieveOps = baseUow.getRetrievalOperations().length > 0;
|
|
798
|
+
if (!hasRetrieveOps) {
|
|
799
|
+
if (options.retryPolicy) {
|
|
800
|
+
throw new Error(
|
|
801
|
+
"Retry policy is only supported when the transaction includes retrieve operations.",
|
|
802
|
+
);
|
|
803
|
+
}
|
|
804
|
+
retryPolicy = new NoRetryPolicy();
|
|
805
|
+
} else {
|
|
806
|
+
retryPolicy =
|
|
807
|
+
options.retryPolicy ??
|
|
808
|
+
new ExponentialBackoffRetryPolicy({
|
|
809
|
+
maxRetries: 5,
|
|
810
|
+
initialDelayMs: 10,
|
|
811
|
+
maxDelayMs: 100,
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
const allRetrieveResults = await baseUow.executeRetrieve();
|
|
816
|
+
if (options.onAfterRetrieve) {
|
|
817
|
+
await options.onAfterRetrieve(baseUow, allRetrieveResults);
|
|
818
|
+
}
|
|
768
819
|
|
|
769
820
|
// Get retrieve results from TypedUnitOfWork's retrievalPhase or default to empty array
|
|
770
821
|
const retrieveResult: TRetrieveResults = typedUowFromRetrieve
|
|
@@ -827,7 +878,7 @@ async function executeTx(
|
|
|
827
878
|
mutateResult = callbacks.mutate(mutateCtx);
|
|
828
879
|
}
|
|
829
880
|
|
|
830
|
-
if (options.onBeforeMutate) {
|
|
881
|
+
if (!options.planMode && options.onBeforeMutate) {
|
|
831
882
|
options.onBeforeMutate(baseUow);
|
|
832
883
|
}
|
|
833
884
|
const result = await baseUow.executeMutations();
|
|
@@ -870,7 +921,7 @@ async function executeTx(
|
|
|
870
921
|
finalResult = serviceFinalResults;
|
|
871
922
|
}
|
|
872
923
|
|
|
873
|
-
if (options.onAfterMutate) {
|
|
924
|
+
if (!options.planMode && options.onAfterMutate) {
|
|
874
925
|
await options.onAfterMutate(baseUow);
|
|
875
926
|
}
|
|
876
927
|
|
|
@@ -885,6 +936,10 @@ async function executeTx(
|
|
|
885
936
|
throw error;
|
|
886
937
|
}
|
|
887
938
|
|
|
939
|
+
if (!retryPolicy) {
|
|
940
|
+
throw error;
|
|
941
|
+
}
|
|
942
|
+
|
|
888
943
|
if (!retryPolicy.shouldRetry(attempt, error, signal)) {
|
|
889
944
|
if (signal?.aborted) {
|
|
890
945
|
throw new Error("Transaction execution aborted");
|
|
@@ -1538,6 +1593,7 @@ interface HandlerTxBuilderState<
|
|
|
1538
1593
|
> {
|
|
1539
1594
|
options: ExecuteTxOptions;
|
|
1540
1595
|
hooks?: THooks;
|
|
1596
|
+
executeWrapper?: <T>(run: () => Promise<T>) => Promise<T>;
|
|
1541
1597
|
withServiceCallsFn?: () => TServiceCalls;
|
|
1542
1598
|
retrieveFn?: (context: {
|
|
1543
1599
|
forSchema: <S extends AnySchema, H extends HooksMap = THooks>(
|
|
@@ -1874,22 +1930,24 @@ export class HandlerTxBuilder<
|
|
|
1874
1930
|
: undefined,
|
|
1875
1931
|
};
|
|
1876
1932
|
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1933
|
+
const run = () =>
|
|
1934
|
+
executeTx(callbacks as Parameters<typeof executeTx>[0], state.options) as Promise<
|
|
1935
|
+
AwaitedPromisesInObject<
|
|
1936
|
+
InferBuilderResultType<
|
|
1937
|
+
TRetrieveResults,
|
|
1938
|
+
TRetrieveSuccessResult,
|
|
1939
|
+
TServiceCalls,
|
|
1940
|
+
TMutateResult,
|
|
1941
|
+
TTransformResult,
|
|
1942
|
+
HasTransform,
|
|
1943
|
+
HasMutate,
|
|
1944
|
+
HasTransformRetrieve,
|
|
1945
|
+
HasRetrieve
|
|
1946
|
+
>
|
|
1890
1947
|
>
|
|
1891
|
-
|
|
1892
|
-
|
|
1948
|
+
>;
|
|
1949
|
+
|
|
1950
|
+
return state.executeWrapper ? state.executeWrapper(run) : run();
|
|
1893
1951
|
}
|
|
1894
1952
|
}
|
|
1895
1953
|
|
|
@@ -1899,9 +1957,11 @@ export class HandlerTxBuilder<
|
|
|
1899
1957
|
export function createHandlerTxBuilder<THooks extends HooksMap = {}>(
|
|
1900
1958
|
options: ExecuteTxOptions,
|
|
1901
1959
|
hooks?: THooks,
|
|
1960
|
+
executeWrapper?: <T>(run: () => Promise<T>) => Promise<T>,
|
|
1902
1961
|
): HandlerTxBuilder<readonly [], [], [], unknown, unknown, false, false, false, false, THooks> {
|
|
1903
1962
|
return new HandlerTxBuilder({
|
|
1904
1963
|
options,
|
|
1905
1964
|
hooks,
|
|
1965
|
+
executeWrapper,
|
|
1906
1966
|
});
|
|
1907
1967
|
}
|