@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,54 +1,230 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { DurableHooksLogger } from "./hooks/durable-hooks-logger.js";
|
|
2
|
+
import { getDurableHooksRuntimeByConfig, getDurableHooksRuntimeByNamespace, registerDurableHooksRuntime } from "./hooks/durable-hooks-runtime.js";
|
|
3
|
+
import { createDurableHooksRunner, prepareHookMutations } from "./hooks/hooks.js";
|
|
4
|
+
import { sanitizeNamespace } from "./naming/sql-naming.js";
|
|
5
|
+
import { HandlerTxBuilder, createHandlerTxBuilder, createServiceTxBuilder } from "./query/unit-of-work/execute-unit-of-work.js";
|
|
6
|
+
import { resolveDatabaseAdapter } from "./util/default-database-adapter.js";
|
|
7
|
+
import { FragmentDefinitionBuilder } from "@fragno-dev/core";
|
|
8
|
+
import { FragnoApiError } from "@fragno-dev/core/api";
|
|
3
9
|
|
|
4
10
|
//#region src/db-fragment-definition-builder.ts
|
|
5
11
|
/**
|
|
6
12
|
* Create database context from options.
|
|
7
13
|
* This extracts the database adapter and creates the ORM instance.
|
|
8
14
|
*/
|
|
9
|
-
function createDatabaseContext(options, schema
|
|
10
|
-
const databaseAdapter = options
|
|
11
|
-
|
|
15
|
+
function createDatabaseContext(options, schema) {
|
|
16
|
+
const databaseAdapter = resolveDatabaseAdapter(options, schema);
|
|
17
|
+
const namespace = resolveDatabaseNamespace(options, schema);
|
|
12
18
|
return {
|
|
13
19
|
databaseAdapter,
|
|
14
20
|
db: databaseAdapter.createQueryEngine(schema, namespace)
|
|
15
21
|
};
|
|
16
22
|
}
|
|
23
|
+
function resolveDatabaseNamespace(options, schema) {
|
|
24
|
+
return options.databaseNamespace !== void 0 ? options.databaseNamespace ?? null : sanitizeNamespace(schema.name);
|
|
25
|
+
}
|
|
26
|
+
function resolveMountRoute(name, mountRoute) {
|
|
27
|
+
const resolved = mountRoute ?? `/api/${name}`;
|
|
28
|
+
return resolved.endsWith("/") ? resolved.slice(0, -1) : resolved;
|
|
29
|
+
}
|
|
30
|
+
const dbRoundtripGuardStateSymbol = Symbol("fragno-db-roundtrip-guard");
|
|
31
|
+
const requestSourceSymbol = Symbol.for("fragno-request-source");
|
|
32
|
+
const requestRouteSymbol = Symbol.for("fragno-request-route");
|
|
33
|
+
const requestWaitUntilSymbol = Symbol.for("fragno-request-wait-until");
|
|
34
|
+
const roundtripGuardDocsUrl = "https://fragno.dev/docs/fragno/for-library-authors/rules-of-fragno";
|
|
35
|
+
function wrapHandlerTxBuilderWithRoundtripGuard(builder, onExecute) {
|
|
36
|
+
const wrappedBuilders = /* @__PURE__ */ new WeakSet();
|
|
37
|
+
const applyExecuteGuard = (target) => {
|
|
38
|
+
if (wrappedBuilders.has(target)) return target;
|
|
39
|
+
wrappedBuilders.add(target);
|
|
40
|
+
const execute = target.execute.bind(target);
|
|
41
|
+
target.execute = () => {
|
|
42
|
+
onExecute();
|
|
43
|
+
return execute();
|
|
44
|
+
};
|
|
45
|
+
return target;
|
|
46
|
+
};
|
|
47
|
+
const wrap = (target) => {
|
|
48
|
+
const guarded = applyExecuteGuard(target);
|
|
49
|
+
return new Proxy(guarded, { get(obj, prop, receiver) {
|
|
50
|
+
const value = Reflect.get(obj, prop, receiver);
|
|
51
|
+
if (typeof value !== "function") return value;
|
|
52
|
+
if (prop === "execute") return value;
|
|
53
|
+
return (...args) => {
|
|
54
|
+
const result = value.apply(obj, args);
|
|
55
|
+
if (result instanceof HandlerTxBuilder) return wrap(result);
|
|
56
|
+
return result;
|
|
57
|
+
};
|
|
58
|
+
} });
|
|
59
|
+
};
|
|
60
|
+
return wrap(builder);
|
|
61
|
+
}
|
|
62
|
+
function buildDurableHooksLogContext(context) {
|
|
63
|
+
const logContext = {};
|
|
64
|
+
if (context?.route !== void 0) logContext["route"] = context.route;
|
|
65
|
+
if (context?.source !== void 0) logContext["source"] = context.source;
|
|
66
|
+
return logContext;
|
|
67
|
+
}
|
|
68
|
+
function notifyDurableHooks(notifier, namespace, notifyContext, logContextFields, options) {
|
|
69
|
+
const suffix = options?.crossNamespace ?? false ? " (cross-namespace)" : "";
|
|
70
|
+
const notifyStart = Date.now();
|
|
71
|
+
DurableHooksLogger.debug(`Durable hooks notify requested${suffix}`, {
|
|
72
|
+
namespace,
|
|
73
|
+
fields: logContextFields
|
|
74
|
+
});
|
|
75
|
+
const notifyPromise = Promise.resolve().then(() => notifier.notify(notifyContext)).then((processed) => {
|
|
76
|
+
DurableHooksLogger.debug(`Durable hooks notify completed${suffix}`, {
|
|
77
|
+
namespace,
|
|
78
|
+
fields: {
|
|
79
|
+
result: processed === void 0 ? null : processed,
|
|
80
|
+
ms: Date.now() - notifyStart,
|
|
81
|
+
...logContextFields
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}).catch((error) => {
|
|
85
|
+
DurableHooksLogger.error(`Durable hooks notify failed${suffix}`, {
|
|
86
|
+
namespace,
|
|
87
|
+
fields: {
|
|
88
|
+
error: DurableHooksLogger.toErrorMessage(error),
|
|
89
|
+
...logContextFields
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
if (notifyContext.waitUntil) {
|
|
94
|
+
notifyContext.waitUntil(notifyPromise);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function notifyDurableHooksAfterMutate({ uow, hooksConfig, internalFragment, autoSchedule, planMode, logContext }) {
|
|
99
|
+
if (planMode) return;
|
|
100
|
+
const notifyContext = {
|
|
101
|
+
source: logContext?.source ?? "request",
|
|
102
|
+
route: logContext?.route,
|
|
103
|
+
waitUntil: logContext?.waitUntil
|
|
104
|
+
};
|
|
105
|
+
const logContextFields = buildDurableHooksLogContext(logContext);
|
|
106
|
+
const triggeredHooks = uow.getTriggeredHooks();
|
|
107
|
+
const ownNamespaceTriggeredCount = hooksConfig ? triggeredHooks.filter((hook) => hook.namespace === hooksConfig.namespace).length : 0;
|
|
108
|
+
if (hooksConfig?.notifier && autoSchedule && ownNamespaceTriggeredCount > 0) notifyDurableHooks(hooksConfig.notifier, hooksConfig.namespace, notifyContext, logContextFields);
|
|
109
|
+
else if (hooksConfig && !autoSchedule && ownNamespaceTriggeredCount > 0) DurableHooksLogger.debug("Durable hooks notify skipped (autoSchedule=false)", {
|
|
110
|
+
namespace: hooksConfig.namespace,
|
|
111
|
+
fields: {
|
|
112
|
+
queued: ownNamespaceTriggeredCount,
|
|
113
|
+
...logContextFields
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
else if (hooksConfig && !hooksConfig.notifier && ownNamespaceTriggeredCount > 0) DurableHooksLogger.debug("Durable hooks notify skipped (notifier missing)", {
|
|
117
|
+
namespace: hooksConfig.namespace,
|
|
118
|
+
fields: {
|
|
119
|
+
queued: ownNamespaceTriggeredCount,
|
|
120
|
+
...logContextFields
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
if (triggeredHooks.length === 0) return;
|
|
124
|
+
const namespaces = /* @__PURE__ */ new Set();
|
|
125
|
+
const triggeredCountByNamespace = /* @__PURE__ */ new Map();
|
|
126
|
+
for (const hook of triggeredHooks) {
|
|
127
|
+
namespaces.add(hook.namespace);
|
|
128
|
+
triggeredCountByNamespace.set(hook.namespace, (triggeredCountByNamespace.get(hook.namespace) ?? 0) + 1);
|
|
129
|
+
}
|
|
130
|
+
if (hooksConfig) namespaces.delete(hooksConfig.namespace);
|
|
131
|
+
for (const namespace of namespaces) {
|
|
132
|
+
if (!internalFragment) {
|
|
133
|
+
DurableHooksLogger.debug("Durable hooks notifier missing scope for namespace", {
|
|
134
|
+
namespace,
|
|
135
|
+
fields: logContextFields
|
|
136
|
+
});
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const runtime = getDurableHooksRuntimeByNamespace(namespace, internalFragment);
|
|
140
|
+
if (!runtime) {
|
|
141
|
+
DurableHooksLogger.debug("Durable hooks notifier missing for namespace", {
|
|
142
|
+
namespace,
|
|
143
|
+
fields: logContextFields
|
|
144
|
+
});
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (runtime.config.autoSchedule === false) {
|
|
148
|
+
DurableHooksLogger.debug("Durable hooks notify skipped (autoSchedule=false)", {
|
|
149
|
+
namespace,
|
|
150
|
+
fields: {
|
|
151
|
+
queued: triggeredCountByNamespace.get(namespace) ?? 0,
|
|
152
|
+
...logContextFields
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const notifier = runtime.config.notifier;
|
|
158
|
+
if (!notifier) {
|
|
159
|
+
DurableHooksLogger.debug("Durable hooks notifier missing for namespace", {
|
|
160
|
+
namespace,
|
|
161
|
+
fields: logContextFields
|
|
162
|
+
});
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
notifyDurableHooks(notifier, namespace, notifyContext, logContextFields, { crossNamespace: true });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function resolveDbRoundtripGuard(options) {
|
|
169
|
+
const guard = options.dbRoundtripGuard;
|
|
170
|
+
if (!guard) return null;
|
|
171
|
+
if (guard === true) return {
|
|
172
|
+
retrieveCount: 0,
|
|
173
|
+
mutateCount: 0,
|
|
174
|
+
maxRoundtrips: 1
|
|
175
|
+
};
|
|
176
|
+
return {
|
|
177
|
+
retrieveCount: 0,
|
|
178
|
+
mutateCount: 0,
|
|
179
|
+
maxRoundtrips: guard.maxRoundtrips ?? 1
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function getDbRoundtripGuardState(storage, guard) {
|
|
183
|
+
const storageWithGuard = storage;
|
|
184
|
+
if (!storageWithGuard[dbRoundtripGuardStateSymbol]) storageWithGuard[dbRoundtripGuardStateSymbol] = { ...guard };
|
|
185
|
+
else storageWithGuard[dbRoundtripGuardStateSymbol].maxRoundtrips = guard.maxRoundtrips;
|
|
186
|
+
return storageWithGuard[dbRoundtripGuardStateSymbol];
|
|
187
|
+
}
|
|
188
|
+
function isRouteRequest(storage) {
|
|
189
|
+
return storage[requestSourceSymbol] === "route";
|
|
190
|
+
}
|
|
17
191
|
/**
|
|
18
192
|
* Builder for database fragments that wraps the core fragment builder
|
|
19
193
|
* and provides database-specific functionality.
|
|
20
194
|
*
|
|
21
|
-
* Database fragments
|
|
195
|
+
* Database fragments use FragnoPublicConfigWithDatabase and default the adapter when possible.
|
|
22
196
|
*/
|
|
23
197
|
var DatabaseFragmentDefinitionBuilder = class DatabaseFragmentDefinitionBuilder {
|
|
24
198
|
#baseBuilder;
|
|
25
199
|
#schema;
|
|
26
|
-
#namespace;
|
|
27
200
|
#hooksFactory;
|
|
28
|
-
|
|
201
|
+
#syncRegistry;
|
|
202
|
+
#registryResolver;
|
|
203
|
+
constructor(baseBuilder, schema, hooksFactory, syncRegistry, registryResolver) {
|
|
29
204
|
this.#baseBuilder = baseBuilder;
|
|
30
205
|
this.#schema = schema;
|
|
31
|
-
this.#namespace = namespace ?? baseBuilder.name;
|
|
32
206
|
this.#hooksFactory = hooksFactory;
|
|
207
|
+
this.#syncRegistry = syncRegistry;
|
|
208
|
+
this.#registryResolver = registryResolver;
|
|
33
209
|
}
|
|
34
210
|
/**
|
|
35
211
|
* Define dependencies for this database fragment.
|
|
36
|
-
* The context includes database adapter
|
|
212
|
+
* The context includes the database adapter.
|
|
37
213
|
*/
|
|
38
214
|
withDependencies(fn) {
|
|
39
215
|
const wrappedFn = (context) => {
|
|
40
|
-
const dbContext = createDatabaseContext(context.options, this.#schema
|
|
216
|
+
const dbContext = createDatabaseContext(context.options, this.#schema);
|
|
217
|
+
const namespace = resolveDatabaseNamespace(context.options, this.#schema);
|
|
41
218
|
const userDeps = fn({
|
|
42
219
|
config: context.config,
|
|
43
220
|
options: context.options,
|
|
44
|
-
db: dbContext.db,
|
|
45
221
|
databaseAdapter: dbContext.databaseAdapter
|
|
46
222
|
});
|
|
47
223
|
const createUow = () => dbContext.db.createUnitOfWork();
|
|
48
224
|
const implicitDeps = {
|
|
49
|
-
|
|
225
|
+
databaseAdapter: dbContext.databaseAdapter,
|
|
50
226
|
schema: this.#schema,
|
|
51
|
-
namespace
|
|
227
|
+
namespace,
|
|
52
228
|
createUnitOfWork: createUow
|
|
53
229
|
};
|
|
54
230
|
return {
|
|
@@ -56,13 +232,13 @@ var DatabaseFragmentDefinitionBuilder = class DatabaseFragmentDefinitionBuilder
|
|
|
56
232
|
...implicitDeps
|
|
57
233
|
};
|
|
58
234
|
};
|
|
59
|
-
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.withDependencies(wrappedFn), this.#schema, this.#
|
|
235
|
+
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.withDependencies(wrappedFn), this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
|
|
60
236
|
}
|
|
61
237
|
providesBaseService(fn) {
|
|
62
|
-
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.providesBaseService(fn), this.#schema, this.#
|
|
238
|
+
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.providesBaseService(fn), this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
|
|
63
239
|
}
|
|
64
240
|
providesService(serviceName, fn) {
|
|
65
|
-
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.providesService(serviceName, fn), this.#schema, this.#
|
|
241
|
+
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.providesService(serviceName, fn), this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
|
|
66
242
|
}
|
|
67
243
|
/**
|
|
68
244
|
* Provide a private service that is only accessible to the fragment author.
|
|
@@ -72,7 +248,7 @@ var DatabaseFragmentDefinitionBuilder = class DatabaseFragmentDefinitionBuilder
|
|
|
72
248
|
* to later ones.
|
|
73
249
|
*/
|
|
74
250
|
providesPrivateService(serviceName, fn) {
|
|
75
|
-
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.providesPrivateService(serviceName, fn), this.#schema, this.#
|
|
251
|
+
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.providesPrivateService(serviceName, fn), this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
|
|
76
252
|
}
|
|
77
253
|
/**
|
|
78
254
|
* Define durable hooks for this fragment.
|
|
@@ -99,26 +275,36 @@ var DatabaseFragmentDefinitionBuilder = class DatabaseFragmentDefinitionBuilder
|
|
|
99
275
|
return fn({
|
|
100
276
|
config: context.config,
|
|
101
277
|
options: context.options,
|
|
278
|
+
deps: context.deps,
|
|
279
|
+
services: context.services,
|
|
280
|
+
serviceDeps: context.serviceDeps,
|
|
102
281
|
defineHook
|
|
103
282
|
});
|
|
104
283
|
};
|
|
105
|
-
const newBuilder = new DatabaseFragmentDefinitionBuilder(this.#baseBuilder, this.#schema, this.#
|
|
284
|
+
const newBuilder = new DatabaseFragmentDefinitionBuilder(this.#baseBuilder, this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
|
|
106
285
|
newBuilder.#hooksFactory = hooksFactory;
|
|
107
286
|
return newBuilder;
|
|
108
287
|
}
|
|
109
288
|
/**
|
|
289
|
+
* Register sync command definitions for this fragment.
|
|
290
|
+
*/
|
|
291
|
+
withSyncCommands(registry) {
|
|
292
|
+
if (registry.schemaName !== this.#schema.name) throw new Error(`Sync command registry schema name "${registry.schemaName}" does not match fragment schema "${this.#schema.name}".`);
|
|
293
|
+
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder, this.#schema, this.#hooksFactory, registry, this.#registryResolver);
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
110
296
|
* Declare that this fragment uses a required service provided by the runtime.
|
|
111
297
|
* Delegates to the base builder.
|
|
112
298
|
*/
|
|
113
299
|
usesService(serviceName) {
|
|
114
|
-
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.usesService(serviceName), this.#schema, this.#
|
|
300
|
+
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.usesService(serviceName), this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
|
|
115
301
|
}
|
|
116
302
|
/**
|
|
117
303
|
* Declare that this fragment uses an optional service provided by the runtime.
|
|
118
304
|
* Delegates to the base builder.
|
|
119
305
|
*/
|
|
120
306
|
usesOptionalService(serviceName) {
|
|
121
|
-
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.usesOptionalService(serviceName), this.#schema, this.#
|
|
307
|
+
return new DatabaseFragmentDefinitionBuilder(this.#baseBuilder.usesOptionalService(serviceName), this.#schema, this.#hooksFactory, this.#syncRegistry, this.#registryResolver);
|
|
122
308
|
}
|
|
123
309
|
/**
|
|
124
310
|
* Build the final database fragment definition.
|
|
@@ -137,11 +323,34 @@ var DatabaseFragmentDefinitionBuilder = class DatabaseFragmentDefinitionBuilder
|
|
|
137
323
|
userDeps = {};
|
|
138
324
|
} else throw error;
|
|
139
325
|
}
|
|
140
|
-
const
|
|
326
|
+
const dbContext = createDatabaseContext(context.options, this.#schema);
|
|
327
|
+
const { db } = dbContext;
|
|
328
|
+
const namespace = resolveDatabaseNamespace(context.options, this.#schema);
|
|
329
|
+
const dryRun = process.env["FRAGNO_INIT_DRY_RUN"] === "true";
|
|
330
|
+
const isInternalFragment$1 = baseDef.name === "$fragno-internal-fragment";
|
|
331
|
+
if (!dryRun && !isInternalFragment$1 && this.#registryResolver) {
|
|
332
|
+
const registry = this.#registryResolver.getRegistryForAdapterSync(dbContext.databaseAdapter);
|
|
333
|
+
const outboxEnabled = context.options.outbox?.enabled ?? false;
|
|
334
|
+
registry.registerSchema({
|
|
335
|
+
name: this.#schema.name,
|
|
336
|
+
namespace,
|
|
337
|
+
version: this.#schema.version,
|
|
338
|
+
tables: Object.keys(this.#schema.tables).sort()
|
|
339
|
+
}, {
|
|
340
|
+
name: baseDef.name,
|
|
341
|
+
mountRoute: resolveMountRoute(baseDef.name, context.options.mountRoute)
|
|
342
|
+
}, { outboxEnabled });
|
|
343
|
+
if (this.#syncRegistry) registry.registerSyncCommands({
|
|
344
|
+
fragmentName: baseDef.name,
|
|
345
|
+
schemaName: this.#syncRegistry.schemaName,
|
|
346
|
+
namespace,
|
|
347
|
+
commands: this.#syncRegistry.commands
|
|
348
|
+
});
|
|
349
|
+
}
|
|
141
350
|
const implicitDeps = {
|
|
142
|
-
|
|
351
|
+
databaseAdapter: dbContext.databaseAdapter,
|
|
143
352
|
schema: this.#schema,
|
|
144
|
-
namespace
|
|
353
|
+
namespace,
|
|
145
354
|
createUnitOfWork: () => db.createUnitOfWork()
|
|
146
355
|
};
|
|
147
356
|
return {
|
|
@@ -150,57 +359,238 @@ var DatabaseFragmentDefinitionBuilder = class DatabaseFragmentDefinitionBuilder
|
|
|
150
359
|
};
|
|
151
360
|
};
|
|
152
361
|
const builderWithStorage = this.#baseBuilder.withExternalRequestStorage(({ options }) => {
|
|
153
|
-
return createDatabaseContext(options, this.#schema
|
|
362
|
+
return createDatabaseContext(options, this.#schema).databaseAdapter.contextStorage;
|
|
154
363
|
}).withRequestStorage(({ options }) => {
|
|
155
|
-
return { uow: createDatabaseContext(options, this.#schema
|
|
364
|
+
return { uow: createDatabaseContext(options, this.#schema).db.createBaseUnitOfWork() };
|
|
156
365
|
});
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
366
|
+
const hooksConfigCache = /* @__PURE__ */ new WeakMap();
|
|
367
|
+
const createHooksConfig = (context) => {
|
|
368
|
+
if (!this.#hooksFactory) return;
|
|
369
|
+
const depsKey = typeof context.deps === "object" && context.deps !== null ? context.deps : void 0;
|
|
370
|
+
const namespaceKey = resolveDatabaseNamespace(context.options, this.#schema) ?? this.#schema.name;
|
|
371
|
+
const durableHooksOptions = context.options.durableHooks;
|
|
372
|
+
DurableHooksLogger.configure(durableHooksOptions?.logging, namespaceKey);
|
|
373
|
+
const cachedHooksConfig = depsKey ? hooksConfigCache.get(depsKey) : void 0;
|
|
374
|
+
if (cachedHooksConfig) {
|
|
375
|
+
if (!cachedHooksConfig.hooks && context.services) cachedHooksConfig.hooks = this.#hooksFactory({
|
|
376
|
+
config: context.config,
|
|
377
|
+
options: context.options,
|
|
378
|
+
deps: context.deps,
|
|
379
|
+
services: context.services,
|
|
380
|
+
serviceDeps: context.serviceDeps ?? {}
|
|
381
|
+
});
|
|
382
|
+
return cachedHooksConfig;
|
|
383
|
+
}
|
|
384
|
+
const autoSchedule = durableHooksOptions?.autoSchedule !== false;
|
|
385
|
+
const baseAdapter = resolveDatabaseAdapter(context.options, this.#schema);
|
|
386
|
+
const hookAdapter = baseAdapter.getHookProcessingAdapter?.() ?? baseAdapter;
|
|
387
|
+
const hookOptions = hookAdapter === baseAdapter ? context.options : {
|
|
388
|
+
...context.options,
|
|
389
|
+
databaseAdapter: hookAdapter
|
|
390
|
+
};
|
|
391
|
+
const registryResolver = this.#registryResolver;
|
|
392
|
+
if (!registryResolver) throw new Error("Adapter registry resolver is missing for durable hooks.");
|
|
393
|
+
const dbContextForHooks = createDatabaseContext(hookOptions, this.#schema);
|
|
394
|
+
const hookContextStorage = dbContextForHooks.databaseAdapter.contextStorage;
|
|
395
|
+
const hooksConfig = {
|
|
396
|
+
hooks: context.services ? this.#hooksFactory({
|
|
397
|
+
config: context.config,
|
|
398
|
+
options: context.options,
|
|
399
|
+
deps: context.deps,
|
|
400
|
+
services: context.services,
|
|
401
|
+
serviceDeps: context.serviceDeps ?? {}
|
|
402
|
+
}) : void 0,
|
|
403
|
+
namespace: namespaceKey,
|
|
404
|
+
internalFragment: registryResolver.getInternalFragment(hookAdapter),
|
|
405
|
+
autoSchedule,
|
|
406
|
+
handlerTx: (execOptions) => {
|
|
180
407
|
const userOnBeforeMutate = execOptions?.onBeforeMutate;
|
|
181
408
|
const userOnAfterMutate = execOptions?.onAfterMutate;
|
|
409
|
+
const planMode = execOptions?.planMode ?? false;
|
|
410
|
+
let storageRef = null;
|
|
411
|
+
const getHookWaitUntil = () => {
|
|
412
|
+
if (!hookContextStorage.hasStore()) return;
|
|
413
|
+
return hookContextStorage.getStore()[requestWaitUntilSymbol];
|
|
414
|
+
};
|
|
182
415
|
return createHandlerTxBuilder({
|
|
183
416
|
...execOptions,
|
|
184
417
|
createUnitOfWork: () => {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
418
|
+
const baseUow = dbContextForHooks.db.createBaseUnitOfWork();
|
|
419
|
+
baseUow.registerSchema(hooksConfig.internalFragment.$internal.deps.schema, hooksConfig.internalFragment.$internal.deps.namespace);
|
|
420
|
+
if (storageRef) storageRef.uow = baseUow;
|
|
421
|
+
return baseUow;
|
|
188
422
|
},
|
|
189
423
|
onBeforeMutate: (uow) => {
|
|
190
|
-
if (
|
|
424
|
+
if (!planMode) prepareHookMutations(uow, hooksConfig.internalFragment, hooksConfig.defaultRetryPolicy);
|
|
191
425
|
if (userOnBeforeMutate) userOnBeforeMutate(uow);
|
|
192
426
|
},
|
|
193
427
|
onAfterMutate: async (uow) => {
|
|
194
|
-
|
|
428
|
+
notifyDurableHooksAfterMutate({
|
|
429
|
+
uow,
|
|
430
|
+
hooksConfig,
|
|
431
|
+
internalFragment: hooksConfig.internalFragment,
|
|
432
|
+
autoSchedule,
|
|
433
|
+
planMode,
|
|
434
|
+
logContext: {
|
|
435
|
+
source: "hook",
|
|
436
|
+
waitUntil: getHookWaitUntil()
|
|
437
|
+
}
|
|
438
|
+
});
|
|
195
439
|
if (userOnAfterMutate) await userOnAfterMutate(uow);
|
|
196
440
|
}
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
441
|
+
}, void 0, (run) => hookContextStorage.runWithInitializer(() => {
|
|
442
|
+
const inheritedWaitUntil = getHookWaitUntil();
|
|
443
|
+
storageRef = { uow: null };
|
|
444
|
+
if (inheritedWaitUntil) storageRef[requestWaitUntilSymbol] = inheritedWaitUntil;
|
|
445
|
+
return storageRef;
|
|
446
|
+
}, run));
|
|
447
|
+
},
|
|
448
|
+
stuckProcessingTimeoutMinutes: durableHooksOptions?.stuckProcessingTimeoutMinutes,
|
|
449
|
+
onStuckProcessingHooks: durableHooksOptions?.onStuckProcessingHooks
|
|
450
|
+
};
|
|
451
|
+
hooksConfig.runner = createDurableHooksRunner(hooksConfig);
|
|
452
|
+
registerDurableHooksRuntime(hooksConfig);
|
|
453
|
+
if (depsKey) hooksConfigCache.set(depsKey, hooksConfig);
|
|
454
|
+
return hooksConfig;
|
|
455
|
+
};
|
|
456
|
+
const isInternalFragment = baseDef.name === "$fragno-internal-fragment";
|
|
457
|
+
const finalDef = builderWithStorage.withThisContext(({ storage, config, options, deps }) => {
|
|
458
|
+
const hooksConfig = createHooksConfig({
|
|
459
|
+
config,
|
|
460
|
+
options,
|
|
461
|
+
deps
|
|
462
|
+
});
|
|
463
|
+
const autoSchedule = options.durableHooks?.autoSchedule !== false;
|
|
464
|
+
const registryResolver = this.#registryResolver;
|
|
465
|
+
const databaseAdapter = deps.databaseAdapter ?? resolveDatabaseAdapter(options, this.#schema);
|
|
466
|
+
const internalFragment = isInternalFragment ? void 0 : hooksConfig?.internalFragment ?? registryResolver?.getInternalFragment(databaseAdapter);
|
|
467
|
+
function serviceTx(schema) {
|
|
468
|
+
const uow = storage.getStore()?.uow;
|
|
469
|
+
if (!uow) throw new Error("No UnitOfWork in context. Service must be called within a route handler OR using `withUnitOfWork`.");
|
|
470
|
+
return createServiceTxBuilder(schema, uow, hooksConfig?.hooks);
|
|
471
|
+
}
|
|
472
|
+
const serviceContext = { serviceTx };
|
|
473
|
+
function handlerTx(execOptions) {
|
|
474
|
+
const currentStorage = storage.getStore();
|
|
475
|
+
if (!currentStorage) throw new Error("No storage in context. Handler must be called within a request context.");
|
|
476
|
+
const userOnBeforeMutate = execOptions?.onBeforeMutate;
|
|
477
|
+
const userOnAfterMutate = execOptions?.onAfterMutate;
|
|
478
|
+
const userOnAfterRetrieve = execOptions?.onAfterRetrieve;
|
|
479
|
+
const planMode = execOptions?.planMode ?? false;
|
|
480
|
+
const roundtripGuard = isRouteRequest(currentStorage) ? resolveDbRoundtripGuard(options) : null;
|
|
481
|
+
const roundtripState = roundtripGuard ? getDbRoundtripGuardState(currentStorage, roundtripGuard) : null;
|
|
482
|
+
const routeInfo = currentStorage[requestRouteSymbol];
|
|
483
|
+
const routeWaitUntil = currentStorage[requestWaitUntilSymbol];
|
|
484
|
+
const routeLabel = routeInfo && routeInfo.method && routeInfo.path ? `${routeInfo.method} ${routeInfo.path}` : null;
|
|
485
|
+
const routeSuffix = routeLabel ? ` (route: ${routeLabel})` : "";
|
|
486
|
+
const buildRoundtripError = (kind) => new FragnoApiError({
|
|
487
|
+
message: `[fragno-db] Fragment "${baseDef.name}" executed more than ${roundtripState?.maxRoundtrips ?? 1} ${kind} database roundtrip(s) in a single request${routeSuffix}. Combine reads/writes into one handlerTx() or increase dbRoundtripGuard. See ${roundtripGuardDocsUrl}`,
|
|
488
|
+
code: "DB_ROUNDTRIP_LIMIT_EXCEEDED"
|
|
489
|
+
}, 500);
|
|
490
|
+
const roundtripExecutionState = roundtripState ? {
|
|
491
|
+
countedRetrieve: false,
|
|
492
|
+
countedMutate: false
|
|
493
|
+
} : null;
|
|
494
|
+
const resetRoundtripExecutionState = () => {
|
|
495
|
+
if (!roundtripExecutionState) return;
|
|
496
|
+
roundtripExecutionState.countedRetrieve = false;
|
|
497
|
+
roundtripExecutionState.countedMutate = false;
|
|
202
498
|
};
|
|
203
|
-
|
|
499
|
+
const guardOnAfterRetrieve = roundtripState ? async (uow, results) => {
|
|
500
|
+
if (roundtripExecutionState && !roundtripExecutionState.countedRetrieve && uow.getRetrievalOperations().length > 0) {
|
|
501
|
+
roundtripExecutionState.countedRetrieve = true;
|
|
502
|
+
roundtripState.retrieveCount += 1;
|
|
503
|
+
if (roundtripState.retrieveCount > roundtripState.maxRoundtrips) throw buildRoundtripError("retrieve");
|
|
504
|
+
}
|
|
505
|
+
if (userOnAfterRetrieve) await userOnAfterRetrieve(uow, results);
|
|
506
|
+
} : userOnAfterRetrieve;
|
|
507
|
+
const builder = createHandlerTxBuilder({
|
|
508
|
+
...execOptions,
|
|
509
|
+
createUnitOfWork: () => {
|
|
510
|
+
currentStorage.uow.reset();
|
|
511
|
+
if (internalFragment) currentStorage.uow.registerSchema(internalFragment.$internal.deps.schema, internalFragment.$internal.deps.namespace);
|
|
512
|
+
return currentStorage.uow;
|
|
513
|
+
},
|
|
514
|
+
onBeforeMutate: (uow) => {
|
|
515
|
+
if (internalFragment && !planMode) prepareHookMutations(uow, internalFragment, hooksConfig?.defaultRetryPolicy);
|
|
516
|
+
if (userOnBeforeMutate) userOnBeforeMutate(uow);
|
|
517
|
+
if (roundtripState && roundtripExecutionState && !roundtripExecutionState.countedMutate && uow.getMutationOperations().length > 0) {
|
|
518
|
+
roundtripExecutionState.countedMutate = true;
|
|
519
|
+
roundtripState.mutateCount += 1;
|
|
520
|
+
if (roundtripState.mutateCount > roundtripState.maxRoundtrips) throw buildRoundtripError("mutate");
|
|
521
|
+
}
|
|
522
|
+
},
|
|
523
|
+
onAfterRetrieve: guardOnAfterRetrieve,
|
|
524
|
+
onAfterMutate: async (uow) => {
|
|
525
|
+
notifyDurableHooksAfterMutate({
|
|
526
|
+
uow,
|
|
527
|
+
hooksConfig,
|
|
528
|
+
internalFragment,
|
|
529
|
+
autoSchedule,
|
|
530
|
+
planMode,
|
|
531
|
+
logContext: {
|
|
532
|
+
route: routeLabel,
|
|
533
|
+
source: "request",
|
|
534
|
+
waitUntil: routeWaitUntil
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
if (hooksConfig && !planMode) {
|
|
538
|
+
const runtimeState = getDurableHooksRuntimeByConfig(hooksConfig);
|
|
539
|
+
if (runtimeState && !runtimeState.dispatcherRegistered && !runtimeState.dispatcherWarningEmitted) {
|
|
540
|
+
if (uow.getTriggeredHooks().some((hook) => hook.namespace === hooksConfig.namespace)) {
|
|
541
|
+
runtimeState.dispatcherWarningEmitted = true;
|
|
542
|
+
DurableHooksLogger.warn("Durable hooks dispatcher not configured for fragment", {
|
|
543
|
+
namespace: hooksConfig.namespace,
|
|
544
|
+
fields: { guidance: "Hooks will only run during requests; scheduled/retry hooks may stall. Create a dispatcher with createDurableHooksProcessor([...]) from `@fragno-dev/db/dispatchers/node` or `@fragno-dev/db/dispatchers/cloudflare-do`." }
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
if (userOnAfterMutate) await userOnAfterMutate(uow);
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
if (roundtripState) return wrapHandlerTxBuilderWithRoundtripGuard(builder, resetRoundtripExecutionState);
|
|
553
|
+
return builder;
|
|
554
|
+
}
|
|
555
|
+
function callServices(serviceCalls) {
|
|
556
|
+
let callWasArray = false;
|
|
557
|
+
return handlerTx().withServiceCalls(() => {
|
|
558
|
+
const calls = serviceCalls();
|
|
559
|
+
callWasArray = Array.isArray(calls);
|
|
560
|
+
return callWasArray ? calls : [calls];
|
|
561
|
+
}).execute().then((result) => callWasArray ? result : result[0]);
|
|
562
|
+
}
|
|
563
|
+
return {
|
|
564
|
+
serviceContext,
|
|
565
|
+
handlerContext: {
|
|
566
|
+
handlerTx,
|
|
567
|
+
callServices
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
}).build();
|
|
571
|
+
if (this.#hooksFactory) finalDef.internalDataFactory = ({ config, options, deps, services, serviceDeps }) => {
|
|
572
|
+
const hooksConfig = createHooksConfig({
|
|
573
|
+
config,
|
|
574
|
+
options,
|
|
575
|
+
deps,
|
|
576
|
+
services,
|
|
577
|
+
serviceDeps
|
|
578
|
+
});
|
|
579
|
+
if (!hooksConfig) return {};
|
|
580
|
+
return { durableHooksToken: registerDurableHooksRuntime(hooksConfig) };
|
|
581
|
+
};
|
|
582
|
+
if (this.#registryResolver) {
|
|
583
|
+
const registryInternalRoutes = ({ deps }) => {
|
|
584
|
+
const databaseAdapter = deps.databaseAdapter;
|
|
585
|
+
if (!databaseAdapter) throw new Error("Database adapter is missing for internal routes.");
|
|
586
|
+
const internalFragment = this.#registryResolver.getInternalFragment(databaseAdapter);
|
|
587
|
+
if (!internalFragment) return [];
|
|
588
|
+
return internalFragment.routes ?? [];
|
|
589
|
+
};
|
|
590
|
+
finalDef.internalRoutes = [...finalDef.internalRoutes ?? [], registryInternalRoutes];
|
|
591
|
+
}
|
|
592
|
+
return {
|
|
593
|
+
...finalDef,
|
|
204
594
|
dependencies
|
|
205
595
|
};
|
|
206
596
|
}
|