@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
package/dist/mod.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.js","names":["#namespace","#schema","#adapter"],"sources":["../src/mod.ts"],"sourcesContent":["import type { DatabaseAdapter } from \"./adapters/adapters\";\nimport type { AnySchema } from \"./schema/create\";\nimport type { CursorResult } from \"./query/cursor\";\nimport { Cursor } from \"./query/cursor\";\nimport type { FragnoInstantiatedFragment, AnyFragnoInstantiatedFragment } from \"@fragno-dev/core\";\nimport type {\n FragnoPublicConfigWithDatabase,\n ImplicitDatabaseDependencies,\n} from \"./db-fragment-definition-builder\";\nimport {\n getSchemaVersionFromDatabase,\n type InternalFragmentInstance,\n} from \"./fragments/internal-fragment\";\n\nexport type { DatabaseAdapter, CursorResult };\nexport { Cursor };\n\nexport const fragnoDatabaseFakeSymbol = \"$fragno-database\" as const;\nexport const fragnoDatabaseLibraryVersion = \"0.1\" as const;\n\nexport interface CreateFragnoDatabaseDefinitionOptions<T extends AnySchema> {\n namespace: string;\n schema: T;\n}\n\nexport function isFragnoDatabase(value: unknown): value is FragnoDatabase<AnySchema> {\n if (value instanceof FragnoDatabase) {\n return true;\n }\n\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n return (\n fragnoDatabaseFakeSymbol in value &&\n value[fragnoDatabaseFakeSymbol] === fragnoDatabaseFakeSymbol\n );\n}\n\n/**\n * A Fragno database instance with a bound adapter.\n * Created from a FragnoDatabaseDefinition by calling .create(adapter).\n */\nexport class FragnoDatabase<const T extends AnySchema, TUOWConfig = void> {\n #namespace: string;\n #schema: T;\n #adapter: DatabaseAdapter<TUOWConfig>;\n\n constructor(options: { namespace: string; schema: T; adapter: DatabaseAdapter<TUOWConfig> }) {\n this.#namespace = options.namespace;\n this.#schema = options.schema;\n this.#adapter = options.adapter;\n }\n\n get [fragnoDatabaseFakeSymbol](): typeof fragnoDatabaseFakeSymbol {\n return fragnoDatabaseFakeSymbol;\n }\n\n get namespace() {\n return this.#namespace;\n }\n\n get schema() {\n return this.#schema;\n }\n\n get adapter(): DatabaseAdapter<TUOWConfig> {\n return this.#adapter;\n }\n}\n\nexport {\n DatabaseFragmentDefinitionBuilder,\n type FragnoPublicConfigWithDatabase,\n type DatabaseFragmentContext,\n type DatabaseHandlerContext as DatabaseRequestContext,\n type ImplicitDatabaseDependencies,\n} from \"./db-fragment-definition-builder\";\n\nexport { withDatabase } from \"./with-database\";\n\nexport { decodeCursor, type CursorData } from \"./query/cursor\";\n\nexport {\n createUnitOfWork,\n UnitOfWork,\n TypedUnitOfWork,\n type IUnitOfWork,\n type IUnitOfWorkRestricted,\n type UOWCompiler,\n type UOWExecutor,\n type UOWDecoder,\n} from \"./query/unit-of-work/unit-of-work\";\n\nexport {\n type RetryPolicy,\n NoRetryPolicy,\n ExponentialBackoffRetryPolicy,\n LinearBackoffRetryPolicy,\n} from \"./query/unit-of-work/retry-policy\";\n\nexport {\n ConcurrencyConflictError,\n // Builder pattern exports\n ServiceTxBuilder,\n HandlerTxBuilder,\n createServiceTxBuilder,\n createHandlerTxBuilder,\n type TxResult,\n // Builder context types\n type ServiceBuilderMutateContext,\n type HandlerBuilderMutateContext,\n type BuilderTransformContextWithMutate,\n type BuilderTransformContextWithoutMutate,\n type ExtractServiceRetrieveResults,\n type ExtractServiceFinalResults,\n} from \"./query/unit-of-work/execute-unit-of-work\";\n\nexport type { BoundServices } from \"@fragno-dev/core\";\n\nexport { internalFragmentDef } from \"./fragments/internal-fragment\";\nexport type { InternalFragmentInstance } from \"./fragments/internal-fragment\";\n\nexport type { HookContext, HooksMap, HookFn, HookPayload, TriggerHookOptions } from \"./hooks/hooks\";\n\nexport type AnyFragnoInstantiatedDatabaseFragment = FragnoInstantiatedFragment<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n ImplicitDatabaseDependencies<AnySchema>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n FragnoPublicConfigWithDatabase,\n // Ensure the fragment has the internal fragment linked\n { _fragno_internal: InternalFragmentInstance } & Record<string, AnyFragnoInstantiatedFragment>\n>;\n\n/**\n * Helper function to run migrations for a database fragment.\n * Extracts the database adapter, schema, and namespace from the fragment and runs migrations.\n * This function:\n * 1. Ensures the internal settings fragment is migrated first\n * 2. Retrieves the current database version from the internal fragment\n * 3. Runs migration from current version to target version\n *\n * @param fragment - The instantiated fragment to run migrations for\n * @throws Error if the fragment doesn't have database support or the adapter doesn't support migrations\n *\n * @example\n * ```typescript\n * const fragment = instantiate(myFragmentDef)\n * .withConfig({})\n * .withRoutes([])\n * .withOptions({ databaseAdapter: myAdapter })\n * .build();\n *\n * await migrate(fragment);\n * ```\n */\nexport async function migrate(fragment: AnyFragnoInstantiatedDatabaseFragment): Promise<void> {\n const { options, deps, linkedFragments } = fragment.$internal;\n const adapter = options.databaseAdapter;\n\n // Check if adapter supports prepareMigrations\n if (!adapter.prepareMigrations) {\n throw new Error(\n \"Database adapter does not support prepareMigrations. Please use an adapter that implements this method.\",\n );\n }\n\n const schema = deps.schema;\n const namespace = deps.namespace;\n\n // Step 1: Ensure the internal fragment (settings table) is migrated first\n const internalFragment = linkedFragments._fragno_internal;\n\n if (!internalFragment) {\n throw new Error(\"Internal fragment not found. Please ensure the internal fragment is linked.\");\n }\n\n if (!(await adapter.isConnectionHealthy())) {\n throw new Error(\n \"Database connection is not healthy. Please check your database connection and try again.\",\n );\n }\n\n const internalDeps = internalFragment.$internal.deps;\n const internalSchema = internalDeps.schema;\n const internalNamespace = internalDeps.namespace;\n\n const internalCurrentVersion = await getSchemaVersionFromDatabase(\n internalFragment,\n internalNamespace,\n );\n\n // Migrate internal fragment if needed\n if (internalCurrentVersion < internalSchema.version) {\n const internalMigrations = adapter.prepareMigrations(internalSchema, internalNamespace);\n await internalMigrations.execute(internalCurrentVersion, internalSchema.version);\n }\n\n // Step 2: Get current database version for this fragment's namespace\n const currentVersion = await getSchemaVersionFromDatabase(internalFragment, namespace);\n\n // Step 3: Run the migration from current version to target version\n const targetVersion = schema.version;\n\n if (currentVersion === targetVersion) {\n return;\n }\n\n if (currentVersion > targetVersion) {\n throw new Error(\n `Cannot migrate backwards: current version (${currentVersion}) > target version (${targetVersion})`,\n );\n }\n\n const migrations = adapter.prepareMigrations(schema, namespace);\n await migrations.execute(currentVersion, targetVersion);\n}\n"],"mappings":";;;;;;;;;AAiBA,MAAa,2BAA2B;AACxC,MAAa,+BAA+B;AAO5C,SAAgB,iBAAiB,OAAoD;AACnF,KAAI,iBAAiB,eACnB,QAAO;AAGT,KAAI,OAAO,UAAU,YAAY,UAAU,KACzC,QAAO;AAGT,QACE,4BAA4B,SAC5B,MAAM,8BAA8B;;;;;;AAQxC,IAAa,iBAAb,MAA0E;CACxE;CACA;CACA;CAEA,YAAY,SAAiF;AAC3F,QAAKA,YAAa,QAAQ;AAC1B,QAAKC,SAAU,QAAQ;AACvB,QAAKC,UAAW,QAAQ;;CAG1B,KAAK,4BAA6D;AAChE,SAAO;;CAGT,IAAI,YAAY;AACd,SAAO,MAAKF;;CAGd,IAAI,SAAS;AACX,SAAO,MAAKC;;CAGd,IAAI,UAAuC;AACzC,SAAO,MAAKC;;;;;;;;;;;;;;;;;;;;;;;;;AAiGhB,eAAsB,QAAQ,UAAgE;CAC5F,MAAM,EAAE,SAAS,MAAM,oBAAoB,SAAS;CACpD,MAAM,UAAU,QAAQ;AAGxB,KAAI,CAAC,QAAQ,kBACX,OAAM,IAAI,MACR,0GACD;CAGH,MAAM,SAAS,KAAK;CACpB,MAAM,YAAY,KAAK;CAGvB,MAAM,mBAAmB,gBAAgB;AAEzC,KAAI,CAAC,iBACH,OAAM,IAAI,MAAM,8EAA8E;AAGhG,KAAI,CAAE,MAAM,QAAQ,qBAAqB,CACvC,OAAM,IAAI,MACR,2FACD;CAGH,MAAM,eAAe,iBAAiB,UAAU;CAChD,MAAM,iBAAiB,aAAa;CACpC,MAAM,oBAAoB,aAAa;CAEvC,MAAM,yBAAyB,MAAM,6BACnC,kBACA,kBACD;AAGD,KAAI,yBAAyB,eAAe,QAE1C,OAD2B,QAAQ,kBAAkB,gBAAgB,kBAAkB,CAC9D,QAAQ,wBAAwB,eAAe,QAAQ;CAIlF,MAAM,iBAAiB,MAAM,6BAA6B,kBAAkB,UAAU;CAGtF,MAAM,gBAAgB,OAAO;AAE7B,KAAI,mBAAmB,cACrB;AAGF,KAAI,iBAAiB,cACnB,OAAM,IAAI,MACR,8CAA8C,eAAe,sBAAsB,cAAc,GAClG;AAIH,OADmB,QAAQ,kBAAkB,QAAQ,UAAU,CAC9C,QAAQ,gBAAgB,cAAc"}
|
|
1
|
+
{"version":3,"file":"mod.js","names":["#namespace","#schema","#adapter","internalSchema"],"sources":["../src/mod.ts"],"sourcesContent":["import type { FragnoInstantiatedFragment } from \"@fragno-dev/core\";\n\nimport type { DatabaseAdapter } from \"./adapters/adapters\";\nimport type {\n FragnoPublicConfigWithDatabase,\n ImplicitDatabaseDependencies,\n DatabaseHandlerContext,\n} from \"./db-fragment-definition-builder\";\nimport { getSchemaVersionFromDatabase } from \"./fragments/internal-fragment\";\nimport { getInternalFragment } from \"./internal/adapter-registry\";\nimport type { CursorResult } from \"./query/cursor\";\nimport { Cursor } from \"./query/cursor\";\nimport {\n dbInterval,\n dbNow,\n type DbInterval,\n type DbIntervalInput,\n type DbNow,\n} from \"./query/db-now\";\nimport type { AnySchema } from \"./schema/create\";\n\nexport type { DatabaseAdapter, CursorResult };\nexport { Cursor };\nexport { dbNow, dbInterval };\nexport type { DbNow, DbInterval, DbIntervalInput };\nexport { InMemoryAdapter, type InMemoryAdapterOptions } from \"./adapters/in-memory\";\nexport { internalSchema } from \"./fragments/internal-fragment\";\nexport { getInternalFragment } from \"./internal/adapter-registry\";\n\nexport const fragnoDatabaseFakeSymbol = \"$fragno-database\" as const;\nexport const fragnoDatabaseLibraryVersion = \"0.1\" as const;\n\nexport interface CreateFragnoDatabaseDefinitionOptions<T extends AnySchema> {\n namespace: string | null;\n schema: T;\n}\n\nexport function isFragnoDatabase(value: unknown): value is FragnoDatabase<AnySchema> {\n if (value instanceof FragnoDatabase) {\n return true;\n }\n\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n\n return (\n fragnoDatabaseFakeSymbol in value &&\n value[fragnoDatabaseFakeSymbol] === fragnoDatabaseFakeSymbol\n );\n}\n\n/**\n * A Fragno database instance with a bound adapter.\n * Created from a FragnoDatabaseDefinition by calling .create(adapter).\n */\nexport class FragnoDatabase<const T extends AnySchema, TUOWConfig = void> {\n #namespace: string | null;\n #schema: T;\n #adapter: DatabaseAdapter<TUOWConfig>;\n\n constructor(options: {\n namespace: string | null;\n schema: T;\n adapter: DatabaseAdapter<TUOWConfig>;\n }) {\n this.#namespace = options.namespace;\n this.#schema = options.schema;\n this.#adapter = options.adapter;\n }\n\n get [fragnoDatabaseFakeSymbol](): typeof fragnoDatabaseFakeSymbol {\n return fragnoDatabaseFakeSymbol;\n }\n\n get namespace() {\n return this.#namespace;\n }\n\n get schema() {\n return this.#schema;\n }\n\n get adapter(): DatabaseAdapter<TUOWConfig> {\n return this.#adapter;\n }\n}\n\nexport {\n DatabaseFragmentDefinitionBuilder,\n type DbRoundtripGuardConfig,\n type FragnoPublicConfigWithDatabase,\n type DatabaseFragmentContext,\n type DatabaseServiceContext,\n type DatabaseHandlerContext as DatabaseRequestContext,\n type ImplicitDatabaseDependencies,\n} from \"./db-fragment-definition-builder\";\n\nexport { withDatabase } from \"./with-database\";\n\nexport { decodeCursor, type CursorData } from \"./query/cursor\";\n\nexport {\n createUnitOfWork,\n UnitOfWork,\n TypedUnitOfWork,\n type IUnitOfWork,\n type IUnitOfWorkRestricted,\n type UOWCompiler,\n type UOWExecutor,\n type UOWDecoder,\n} from \"./query/unit-of-work/unit-of-work\";\n\nexport {\n type RetryPolicy,\n NoRetryPolicy,\n ExponentialBackoffRetryPolicy,\n LinearBackoffRetryPolicy,\n} from \"./query/unit-of-work/retry-policy\";\n\nexport {\n ConcurrencyConflictError,\n // Builder pattern exports\n ServiceTxBuilder,\n HandlerTxBuilder,\n createServiceTxBuilder,\n createHandlerTxBuilder,\n serviceCalls,\n type TxResult,\n // Builder context types\n type HandlerTxContext,\n type ServiceBuilderMutateContext,\n type HandlerBuilderMutateContext,\n type BuilderTransformContextWithMutate,\n type BuilderTransformContextWithoutMutate,\n type ExtractServiceRetrieveResults,\n type ExtractServiceFinalResults,\n} from \"./query/unit-of-work/execute-unit-of-work\";\n\nexport type { BoundServices } from \"@fragno-dev/core\";\n\nexport { internalFragmentDef } from \"./fragments/internal-fragment\";\nexport type { InternalFragmentInstance } from \"./fragments/internal-fragment\";\nexport type {\n OutboxConfig,\n OutboxEntry,\n OutboxPayload,\n OutboxMutation,\n OutboxRefMap,\n} from \"./outbox/outbox\";\n\nexport type {\n HookContext,\n HooksMap,\n HookFn,\n HookHandlerTx,\n HookPayload,\n TriggerHookOptions,\n DurableHooksProcessingOptions,\n StuckHookProcessingInfo,\n StuckHookProcessingEvent,\n StuckHookProcessingTimeoutMinutes,\n} from \"./hooks/hooks\";\nexport { defineSyncCommands } from \"./sync/commands\";\nexport type {\n DurableHookRecord,\n DurableHookStatus,\n DurableHooksAccessor,\n DurableHooksService,\n} from \"./durable-hooks\";\nexport { getDurableHooksService } from \"./durable-hooks\";\nexport type {\n SubmitAppliedResponse,\n SubmitConflictReason,\n SubmitConflictResponse,\n SubmitRequest,\n SubmitResponse,\n SyncCommandDefinition,\n SyncCommandHandler,\n SyncCommandRegistry,\n SyncCommandTxFactory,\n} from \"./sync/types\";\n\nexport type AnyFragnoInstantiatedDatabaseFragment<TSchema extends AnySchema = AnySchema> =\n FragnoInstantiatedFragment<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n ImplicitDatabaseDependencies<TSchema>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n DatabaseHandlerContext,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n FragnoPublicConfigWithDatabase\n >;\n\n/**\n * Helper function to run migrations for a database fragment.\n * Extracts the database adapter, schema, and namespace from the fragment and runs migrations.\n * This function:\n * 1. Ensures the internal settings fragment is migrated first\n * 2. Retrieves the current database version from the internal fragment\n * 3. Runs migration from current version to target version\n *\n * @param fragment - The instantiated fragment to run migrations for\n * @throws Error if the fragment doesn't have database support or the adapter doesn't support migrations\n *\n * @example\n * ```typescript\n * const fragment = instantiate(myFragmentDef)\n * .withConfig({})\n * .withRoutes([])\n * .withOptions({ databaseAdapter: myAdapter })\n * .build();\n *\n * await migrate(fragment);\n * ```\n */\nexport async function migrate<TSchema extends AnySchema>(\n fragment: AnyFragnoInstantiatedDatabaseFragment<TSchema>,\n): Promise<void> {\n const { deps } = fragment.$internal;\n const adapter = deps.databaseAdapter;\n\n // Check if adapter supports prepareMigrations\n if (!adapter.prepareMigrations) {\n throw new Error(\n \"Database adapter does not support prepareMigrations. Please use an adapter that implements this method.\",\n );\n }\n\n const schema = deps.schema;\n const namespace = deps.namespace ?? schema.name;\n\n // Step 1: Ensure the internal fragment (settings table) is migrated first\n const internalFragment = getInternalFragment(adapter);\n\n if (!(await adapter.isConnectionHealthy())) {\n throw new Error(\n \"Database connection is not healthy. Please check your database connection and try again.\",\n );\n }\n\n const internalDeps = internalFragment.$internal.deps;\n const internalSchema = internalDeps.schema;\n // Internal fragment uses databaseNamespace: null (no table suffix).\n // Version tracking uses empty string so the key is \".schema_version\",\n // which matches both the legacy format and how the internal fragment was designed.\n const internalNamespace = internalDeps.namespace ?? \"\";\n\n const internalCurrentVersion = await getSchemaVersionFromDatabase(\n internalFragment,\n internalNamespace,\n );\n\n // Migrate internal fragment if needed\n if (internalCurrentVersion < internalSchema.version) {\n const internalMigrations = adapter.prepareMigrations(internalSchema, internalNamespace);\n await internalMigrations.execute(internalCurrentVersion, internalSchema.version);\n }\n\n // Step 2: Get current database version for this fragment's namespace\n const currentVersion = await getSchemaVersionFromDatabase(internalFragment, namespace);\n\n // Step 3: Run the migration from current version to target version\n const targetVersion = schema.version;\n\n if (currentVersion === targetVersion) {\n return;\n }\n\n if (currentVersion > targetVersion) {\n throw new Error(\n `Cannot migrate backwards: current version (${currentVersion}) > target version (${targetVersion})`,\n );\n }\n\n const migrations = adapter.prepareMigrations(schema, namespace);\n await migrations.execute(currentVersion, targetVersion);\n}\n"],"mappings":";;;;;;;;;;;;;;;;AA6BA,MAAa,2BAA2B;AACxC,MAAa,+BAA+B;AAO5C,SAAgB,iBAAiB,OAAoD;AACnF,KAAI,iBAAiB,eACnB,QAAO;AAGT,KAAI,OAAO,UAAU,YAAY,UAAU,KACzC,QAAO;AAGT,QACE,4BAA4B,SAC5B,MAAM,8BAA8B;;;;;;AAQxC,IAAa,iBAAb,MAA0E;CACxE;CACA;CACA;CAEA,YAAY,SAIT;AACD,QAAKA,YAAa,QAAQ;AAC1B,QAAKC,SAAU,QAAQ;AACvB,QAAKC,UAAW,QAAQ;;CAG1B,KAAK,4BAA6D;AAChE,SAAO;;CAGT,IAAI,YAAY;AACd,SAAO,MAAKF;;CAGd,IAAI,SAAS;AACX,SAAO,MAAKC;;CAGd,IAAI,UAAuC;AACzC,SAAO,MAAKC;;;;;;;;;;;;;;;;;;;;;;;;;AAwIhB,eAAsB,QACpB,UACe;CACf,MAAM,EAAE,SAAS,SAAS;CAC1B,MAAM,UAAU,KAAK;AAGrB,KAAI,CAAC,QAAQ,kBACX,OAAM,IAAI,MACR,0GACD;CAGH,MAAM,SAAS,KAAK;CACpB,MAAM,YAAY,KAAK,aAAa,OAAO;CAG3C,MAAM,mBAAmB,oBAAoB,QAAQ;AAErD,KAAI,CAAE,MAAM,QAAQ,qBAAqB,CACvC,OAAM,IAAI,MACR,2FACD;CAGH,MAAM,eAAe,iBAAiB,UAAU;CAChD,MAAMC,mBAAiB,aAAa;CAIpC,MAAM,oBAAoB,aAAa,aAAa;CAEpD,MAAM,yBAAyB,MAAM,6BACnC,kBACA,kBACD;AAGD,KAAI,yBAAyBA,iBAAe,QAE1C,OAD2B,QAAQ,kBAAkBA,kBAAgB,kBAAkB,CAC9D,QAAQ,wBAAwBA,iBAAe,QAAQ;CAIlF,MAAM,iBAAiB,MAAM,6BAA6B,kBAAkB,UAAU;CAGtF,MAAM,gBAAgB,OAAO;AAE7B,KAAI,mBAAmB,cACrB;AAGF,KAAI,iBAAiB,cACnB,OAAM,IAAI,MACR,8CAA8C,eAAe,sBAAsB,cAAc,GAClG;AAIH,OADmB,QAAQ,kBAAkB,QAAQ,UAAU,CAC9C,QAAQ,gBAAgB,cAAc"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/naming/sql-naming.d.ts
|
|
2
|
+
type NamespaceScope = "suffix" | "schema";
|
|
3
|
+
interface SqlNamingStrategy {
|
|
4
|
+
namespaceScope: NamespaceScope;
|
|
5
|
+
namespaceToSchema: (namespace: string) => string;
|
|
6
|
+
tableName: (logicalTable: string, namespace: string | null) => string;
|
|
7
|
+
columnName: (logicalColumn: string, logicalTable: string) => string;
|
|
8
|
+
indexName: (logicalIndex: string, logicalTable: string, namespace: string | null) => string;
|
|
9
|
+
uniqueIndexName: (logicalIndex: string, logicalTable: string, namespace: string | null) => string;
|
|
10
|
+
foreignKeyName: (params: {
|
|
11
|
+
logicalTable: string;
|
|
12
|
+
logicalReferencedTable: string;
|
|
13
|
+
referenceName: string;
|
|
14
|
+
namespace: string | null;
|
|
15
|
+
}) => string;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { SqlNamingStrategy };
|
|
19
|
+
//# sourceMappingURL=sql-naming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-naming.d.ts","names":[],"sources":["../../src/naming/sql-naming.ts"],"sourcesContent":[],"mappings":";AAIY,KAAA,cAAA,GAAc,QAAA,GAAA,QAAA;AAET,UAAA,iBAAA,CAAiB;kBAChB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
//#region src/naming/sql-naming.ts
|
|
4
|
+
const normalizeNamespace = (namespace) => namespace && namespace.length > 0 ? namespace : null;
|
|
5
|
+
const buildNamespaceSuffix = (namespace) => {
|
|
6
|
+
const sanitized = normalizeNamespace(namespace);
|
|
7
|
+
return sanitized ? `_${sanitized}` : "";
|
|
8
|
+
};
|
|
9
|
+
const MAX_IDENTIFIER_LENGTH = 63;
|
|
10
|
+
const HASH_LENGTH = 8;
|
|
11
|
+
const withHash = (value) => {
|
|
12
|
+
return `${value}_${createHash("sha1").update(value).digest("hex").slice(0, 8)}`;
|
|
13
|
+
};
|
|
14
|
+
const truncateWithHash = (value) => {
|
|
15
|
+
if (value.length <= MAX_IDENTIFIER_LENGTH) return value;
|
|
16
|
+
const hash = createHash("sha1").update(value).digest("hex").slice(0, HASH_LENGTH);
|
|
17
|
+
return `${value.slice(0, MAX_IDENTIFIER_LENGTH - HASH_LENGTH)}${hash}`;
|
|
18
|
+
};
|
|
19
|
+
const buildIndexName = (prefix, logicalIndex, logicalTable, namespace) => {
|
|
20
|
+
return `${prefix}_${withHash(`${logicalTable}_${logicalIndex}${buildNamespaceSuffix(namespace)}`)}`;
|
|
21
|
+
};
|
|
22
|
+
const suffixNamingStrategy = {
|
|
23
|
+
namespaceScope: "suffix",
|
|
24
|
+
namespaceToSchema: (namespace) => namespace,
|
|
25
|
+
tableName: (logicalTable, namespace) => {
|
|
26
|
+
const sanitized = normalizeNamespace(namespace);
|
|
27
|
+
return truncateWithHash(sanitized ? `${logicalTable}_${sanitized}` : logicalTable);
|
|
28
|
+
},
|
|
29
|
+
columnName: (logicalColumn) => logicalColumn,
|
|
30
|
+
indexName: (logicalIndex, logicalTable, namespace) => truncateWithHash(buildIndexName("idx", logicalIndex, logicalTable, namespace)),
|
|
31
|
+
uniqueIndexName: (logicalIndex, logicalTable, namespace) => truncateWithHash(buildIndexName("uidx", logicalIndex, logicalTable, namespace)),
|
|
32
|
+
foreignKeyName: ({ logicalTable, logicalReferencedTable, referenceName, namespace }) => {
|
|
33
|
+
return truncateWithHash(`fk_${withHash(`${logicalTable}_${logicalReferencedTable}_${referenceName}${buildNamespaceSuffix(namespace)}`)}`);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const schemaNamingStrategy = {
|
|
37
|
+
namespaceScope: "schema",
|
|
38
|
+
namespaceToSchema: (namespace) => namespace,
|
|
39
|
+
tableName: (logicalTable) => truncateWithHash(logicalTable),
|
|
40
|
+
columnName: (logicalColumn) => logicalColumn,
|
|
41
|
+
indexName: (logicalIndex) => truncateWithHash(logicalIndex),
|
|
42
|
+
uniqueIndexName: (logicalIndex) => truncateWithHash(logicalIndex),
|
|
43
|
+
foreignKeyName: ({ logicalTable, logicalReferencedTable, referenceName }) => truncateWithHash(`fk_${logicalTable}_${logicalReferencedTable}_${referenceName}`)
|
|
44
|
+
};
|
|
45
|
+
var NamingResolver = class {
|
|
46
|
+
#namespace;
|
|
47
|
+
#strategy;
|
|
48
|
+
#tableNameMap = {};
|
|
49
|
+
#columnNameMaps = /* @__PURE__ */ new Map();
|
|
50
|
+
constructor(schema, namespace, strategy) {
|
|
51
|
+
this.#namespace = namespace;
|
|
52
|
+
this.#strategy = strategy;
|
|
53
|
+
for (const table of Object.values(schema.tables)) {
|
|
54
|
+
const physicalTable = this.getTableName(table.name);
|
|
55
|
+
this.#tableNameMap[physicalTable] = table.name;
|
|
56
|
+
const columnMap = {};
|
|
57
|
+
for (const column of Object.values(table.columns)) {
|
|
58
|
+
const physicalColumn = this.getColumnName(table.name, column.name);
|
|
59
|
+
columnMap[physicalColumn] = column.name;
|
|
60
|
+
}
|
|
61
|
+
this.#columnNameMaps.set(table.name, columnMap);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
get namespace() {
|
|
65
|
+
return this.#namespace;
|
|
66
|
+
}
|
|
67
|
+
get strategy() {
|
|
68
|
+
return this.#strategy;
|
|
69
|
+
}
|
|
70
|
+
getSchemaName() {
|
|
71
|
+
if (this.#strategy.namespaceScope !== "schema") return null;
|
|
72
|
+
if (!this.#namespace || this.#namespace.length === 0) return null;
|
|
73
|
+
return this.#strategy.namespaceToSchema(this.#namespace);
|
|
74
|
+
}
|
|
75
|
+
getTableName(logicalTable) {
|
|
76
|
+
return this.#strategy.tableName(logicalTable, this.#namespace);
|
|
77
|
+
}
|
|
78
|
+
getColumnName(logicalTable, logicalColumn) {
|
|
79
|
+
return this.#strategy.columnName(logicalColumn, logicalTable);
|
|
80
|
+
}
|
|
81
|
+
getIndexName(logicalIndex, logicalTable) {
|
|
82
|
+
return this.#strategy.indexName(logicalIndex, logicalTable, this.#namespace);
|
|
83
|
+
}
|
|
84
|
+
getUniqueIndexName(logicalIndex, logicalTable) {
|
|
85
|
+
return this.#strategy.uniqueIndexName(logicalIndex, logicalTable, this.#namespace);
|
|
86
|
+
}
|
|
87
|
+
getForeignKeyName(params) {
|
|
88
|
+
return this.#strategy.foreignKeyName({
|
|
89
|
+
...params,
|
|
90
|
+
namespace: this.#namespace
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
getTableNameMap() {
|
|
94
|
+
return { ...this.#tableNameMap };
|
|
95
|
+
}
|
|
96
|
+
getColumnNameMap(table) {
|
|
97
|
+
const tableName = typeof table === "string" ? table : table.name;
|
|
98
|
+
const map = this.#columnNameMaps.get(tableName);
|
|
99
|
+
return map ? { ...map } : {};
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const createNamingResolver = (schema, namespace, strategy) => new NamingResolver(schema, namespace, strategy);
|
|
103
|
+
/**
|
|
104
|
+
* Sanitizes a namespace for use in SQL identifiers and TypeScript exports.
|
|
105
|
+
* Converts dashes to underscores to ensure compatibility with SQL identifiers.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* sanitizeNamespace("my-fragment") // => "my_fragment"
|
|
109
|
+
*/
|
|
110
|
+
function sanitizeNamespace(namespace) {
|
|
111
|
+
return namespace.replace(/-/g, "_");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
//#endregion
|
|
115
|
+
export { createNamingResolver, sanitizeNamespace, schemaNamingStrategy, suffixNamingStrategy };
|
|
116
|
+
//# sourceMappingURL=sql-naming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-naming.js","names":["suffixNamingStrategy: SqlNamingStrategy","schemaNamingStrategy: SqlNamingStrategy","#namespace","#strategy","#tableNameMap","#columnNameMaps","columnMap: Record<string, string>"],"sources":["../../src/naming/sql-naming.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport type { AnySchema, AnyTable } from \"../schema/create\";\n\nexport type NamespaceScope = \"suffix\" | \"schema\";\n\nexport interface SqlNamingStrategy {\n namespaceScope: NamespaceScope;\n namespaceToSchema: (namespace: string) => string;\n\n tableName: (logicalTable: string, namespace: string | null) => string;\n columnName: (logicalColumn: string, logicalTable: string) => string;\n\n indexName: (logicalIndex: string, logicalTable: string, namespace: string | null) => string;\n uniqueIndexName: (logicalIndex: string, logicalTable: string, namespace: string | null) => string;\n foreignKeyName: (params: {\n logicalTable: string;\n logicalReferencedTable: string;\n referenceName: string;\n namespace: string | null;\n }) => string;\n}\n\nconst normalizeNamespace = (namespace: string | null) =>\n namespace && namespace.length > 0 ? namespace : null;\n\nconst buildNamespaceSuffix = (namespace: string | null) => {\n const sanitized = normalizeNamespace(namespace);\n return sanitized ? `_${sanitized}` : \"\";\n};\n\nconst MAX_IDENTIFIER_LENGTH = 63;\nconst HASH_LENGTH = 8;\n\nconst withHash = (value: string) => {\n const hash = createHash(\"sha1\").update(value).digest(\"hex\").slice(0, 8);\n return `${value}_${hash}`;\n};\n\nconst truncateWithHash = (value: string) => {\n if (value.length <= MAX_IDENTIFIER_LENGTH) {\n return value;\n }\n const hash = createHash(\"sha1\").update(value).digest(\"hex\").slice(0, HASH_LENGTH);\n return `${value.slice(0, MAX_IDENTIFIER_LENGTH - HASH_LENGTH)}${hash}`;\n};\n\nconst buildIndexName = (\n prefix: \"idx\" | \"uidx\",\n logicalIndex: string,\n logicalTable: string,\n namespace: string | null,\n) => {\n const base = `${logicalTable}_${logicalIndex}${buildNamespaceSuffix(namespace)}`;\n return `${prefix}_${withHash(base)}`;\n};\n\nexport const suffixNamingStrategy: SqlNamingStrategy = {\n namespaceScope: \"suffix\",\n namespaceToSchema: (namespace) => namespace,\n tableName: (logicalTable, namespace) => {\n const sanitized = normalizeNamespace(namespace);\n return truncateWithHash(sanitized ? `${logicalTable}_${sanitized}` : logicalTable);\n },\n columnName: (logicalColumn) => logicalColumn,\n indexName: (logicalIndex, logicalTable, namespace) =>\n truncateWithHash(buildIndexName(\"idx\", logicalIndex, logicalTable, namespace)),\n uniqueIndexName: (logicalIndex, logicalTable, namespace) =>\n truncateWithHash(buildIndexName(\"uidx\", logicalIndex, logicalTable, namespace)),\n foreignKeyName: ({ logicalTable, logicalReferencedTable, referenceName, namespace }) => {\n const base = `${logicalTable}_${logicalReferencedTable}_${referenceName}${buildNamespaceSuffix(namespace)}`;\n return truncateWithHash(`fk_${withHash(base)}`);\n },\n};\n\nexport const schemaNamingStrategy: SqlNamingStrategy = {\n namespaceScope: \"schema\",\n namespaceToSchema: (namespace) => namespace,\n tableName: (logicalTable) => truncateWithHash(logicalTable),\n columnName: (logicalColumn) => logicalColumn,\n indexName: (logicalIndex) => truncateWithHash(logicalIndex),\n uniqueIndexName: (logicalIndex) => truncateWithHash(logicalIndex),\n foreignKeyName: ({ logicalTable, logicalReferencedTable, referenceName }) =>\n truncateWithHash(`fk_${logicalTable}_${logicalReferencedTable}_${referenceName}`),\n};\n\nexport class NamingResolver {\n readonly #namespace: string | null;\n readonly #strategy: SqlNamingStrategy;\n readonly #tableNameMap: Record<string, string> = {};\n readonly #columnNameMaps = new Map<string, Record<string, string>>();\n\n constructor(schema: AnySchema, namespace: string | null, strategy: SqlNamingStrategy) {\n this.#namespace = namespace;\n this.#strategy = strategy;\n\n for (const table of Object.values(schema.tables)) {\n const physicalTable = this.getTableName(table.name);\n this.#tableNameMap[physicalTable] = table.name;\n\n const columnMap: Record<string, string> = {};\n for (const column of Object.values(table.columns)) {\n const physicalColumn = this.getColumnName(table.name, column.name);\n columnMap[physicalColumn] = column.name;\n }\n this.#columnNameMaps.set(table.name, columnMap);\n }\n }\n\n get namespace(): string | null {\n return this.#namespace;\n }\n\n get strategy(): SqlNamingStrategy {\n return this.#strategy;\n }\n\n getSchemaName(): string | null {\n if (this.#strategy.namespaceScope !== \"schema\") {\n return null;\n }\n if (!this.#namespace || this.#namespace.length === 0) {\n return null;\n }\n return this.#strategy.namespaceToSchema(this.#namespace);\n }\n\n getTableName(logicalTable: string): string {\n return this.#strategy.tableName(logicalTable, this.#namespace);\n }\n\n getColumnName(logicalTable: string, logicalColumn: string): string {\n return this.#strategy.columnName(logicalColumn, logicalTable);\n }\n\n getIndexName(logicalIndex: string, logicalTable: string): string {\n return this.#strategy.indexName(logicalIndex, logicalTable, this.#namespace);\n }\n\n getUniqueIndexName(logicalIndex: string, logicalTable: string): string {\n return this.#strategy.uniqueIndexName(logicalIndex, logicalTable, this.#namespace);\n }\n\n getForeignKeyName(params: {\n logicalTable: string;\n logicalReferencedTable: string;\n referenceName: string;\n }): string {\n return this.#strategy.foreignKeyName({\n ...params,\n namespace: this.#namespace,\n });\n }\n\n getTableNameMap(): Record<string, string> {\n return { ...this.#tableNameMap };\n }\n\n getColumnNameMap(table: AnyTable | string): Record<string, string> {\n const tableName = typeof table === \"string\" ? table : table.name;\n const map = this.#columnNameMaps.get(tableName);\n return map ? { ...map } : {};\n }\n}\n\nexport const createNamingResolver = (\n schema: AnySchema,\n namespace: string | null,\n strategy: SqlNamingStrategy,\n): NamingResolver => new NamingResolver(schema, namespace, strategy);\n\n/**\n * Sanitizes a namespace for use in SQL identifiers and TypeScript exports.\n * Converts dashes to underscores to ensure compatibility with SQL identifiers.\n *\n * @example\n * sanitizeNamespace(\"my-fragment\") // => \"my_fragment\"\n */\nexport function sanitizeNamespace(namespace: string): string {\n return namespace.replace(/-/g, \"_\");\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { FragnoId, FragnoReference } from "../schema/create.js";
|
|
2
|
+
import { internalSchema } from "../fragments/internal-fragment.schema.js";
|
|
3
|
+
import { encodeVersionstamp, versionstampToHex } from "./outbox.js";
|
|
4
|
+
|
|
5
|
+
//#region src/outbox/outbox-builder.ts
|
|
6
|
+
const INTERNAL_TABLE_NAMES = new Set(Object.keys(internalSchema.tables));
|
|
7
|
+
function buildOutboxPlan(operations) {
|
|
8
|
+
const drafts = [];
|
|
9
|
+
const lookups = [];
|
|
10
|
+
for (const op of operations) {
|
|
11
|
+
if (op.type === "check") continue;
|
|
12
|
+
if (isInternalMutation(op)) continue;
|
|
13
|
+
const table = getTable(op.schema, op.table);
|
|
14
|
+
const schemaName = op.namespace ?? "";
|
|
15
|
+
const namespace = op.namespace ? op.namespace : void 0;
|
|
16
|
+
const mutationIndex = drafts.length;
|
|
17
|
+
if (op.type === "create") {
|
|
18
|
+
drafts.push({
|
|
19
|
+
op: "create",
|
|
20
|
+
schema: schemaName,
|
|
21
|
+
namespace,
|
|
22
|
+
table: op.table,
|
|
23
|
+
externalId: op.generatedExternalId,
|
|
24
|
+
values: encodeOutboxValues({
|
|
25
|
+
table,
|
|
26
|
+
values: op.values,
|
|
27
|
+
mutationIndex,
|
|
28
|
+
namespace,
|
|
29
|
+
lookups
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (op.type === "update") {
|
|
35
|
+
drafts.push({
|
|
36
|
+
op: "update",
|
|
37
|
+
schema: schemaName,
|
|
38
|
+
namespace,
|
|
39
|
+
table: op.table,
|
|
40
|
+
externalId: getExternalId(op.id),
|
|
41
|
+
set: encodeOutboxValues({
|
|
42
|
+
table,
|
|
43
|
+
values: op.set,
|
|
44
|
+
mutationIndex,
|
|
45
|
+
namespace,
|
|
46
|
+
lookups
|
|
47
|
+
}),
|
|
48
|
+
checkVersion: op.checkVersion && op.id instanceof FragnoId ? op.id.version : void 0
|
|
49
|
+
});
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (op.type === "delete") drafts.push({
|
|
53
|
+
op: "delete",
|
|
54
|
+
schema: schemaName,
|
|
55
|
+
namespace,
|
|
56
|
+
table: op.table,
|
|
57
|
+
externalId: getExternalId(op.id),
|
|
58
|
+
checkVersion: op.checkVersion && op.id instanceof FragnoId ? op.id.version : void 0
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
drafts,
|
|
63
|
+
lookups
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function finalizeOutboxPayload(plan, transactionVersion) {
|
|
67
|
+
return {
|
|
68
|
+
version: 1,
|
|
69
|
+
mutations: plan.drafts.map((draft, index) => {
|
|
70
|
+
const versionstamp = versionstampToHex(encodeVersionstamp(transactionVersion, index));
|
|
71
|
+
return {
|
|
72
|
+
...draft,
|
|
73
|
+
versionstamp
|
|
74
|
+
};
|
|
75
|
+
})
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function encodeOutboxValues(options) {
|
|
79
|
+
const { table, values, mutationIndex, namespace, lookups } = options;
|
|
80
|
+
const output = {};
|
|
81
|
+
for (const [key, value] of Object.entries(values)) {
|
|
82
|
+
if (value === void 0) continue;
|
|
83
|
+
if (table.columns[key]?.role === "reference") {
|
|
84
|
+
output[key] = resolveReferenceValue({
|
|
85
|
+
value,
|
|
86
|
+
mutationIndex,
|
|
87
|
+
columnName: key,
|
|
88
|
+
table,
|
|
89
|
+
namespace,
|
|
90
|
+
lookups
|
|
91
|
+
});
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (value instanceof FragnoId) {
|
|
95
|
+
output[key] = value.externalId;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
output[key] = value;
|
|
99
|
+
}
|
|
100
|
+
return output;
|
|
101
|
+
}
|
|
102
|
+
function resolveReferenceValue(options) {
|
|
103
|
+
const { value, mutationIndex, columnName, table, namespace, lookups } = options;
|
|
104
|
+
if (value === null) return null;
|
|
105
|
+
if (value instanceof FragnoId) return value.externalId;
|
|
106
|
+
if (typeof value === "string") return value;
|
|
107
|
+
if (value instanceof FragnoReference) return createReferencePlaceholder({
|
|
108
|
+
internalId: value.internalId,
|
|
109
|
+
mutationIndex,
|
|
110
|
+
columnName,
|
|
111
|
+
table,
|
|
112
|
+
namespace,
|
|
113
|
+
lookups
|
|
114
|
+
});
|
|
115
|
+
if (typeof value === "bigint" || typeof value === "number") return createReferencePlaceholder({
|
|
116
|
+
internalId: value,
|
|
117
|
+
mutationIndex,
|
|
118
|
+
columnName,
|
|
119
|
+
table,
|
|
120
|
+
namespace,
|
|
121
|
+
lookups
|
|
122
|
+
});
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
function createReferencePlaceholder(options) {
|
|
126
|
+
const { internalId, mutationIndex, columnName, table, namespace, lookups } = options;
|
|
127
|
+
const key = `${mutationIndex}.${columnName}`;
|
|
128
|
+
const referencedTable = resolveReferencedTable(table, columnName);
|
|
129
|
+
lookups.push({
|
|
130
|
+
key,
|
|
131
|
+
internalId,
|
|
132
|
+
table: referencedTable,
|
|
133
|
+
namespace
|
|
134
|
+
});
|
|
135
|
+
return { __fragno_ref: key };
|
|
136
|
+
}
|
|
137
|
+
function resolveReferencedTable(table, columnName) {
|
|
138
|
+
for (const relation of Object.values(table.relations)) if (relation.on.some(([localColumn]) => localColumn === columnName)) return relation.table;
|
|
139
|
+
throw new Error(`Reference column ${columnName} not found in table ${table.name}`);
|
|
140
|
+
}
|
|
141
|
+
function getExternalId(id) {
|
|
142
|
+
return typeof id === "string" ? id : id.externalId;
|
|
143
|
+
}
|
|
144
|
+
function isInternalMutation(op) {
|
|
145
|
+
if (op.schema === internalSchema) return true;
|
|
146
|
+
return op.namespace === "" && INTERNAL_TABLE_NAMES.has(op.table);
|
|
147
|
+
}
|
|
148
|
+
function getTable(schema, tableName) {
|
|
149
|
+
const table = schema.tables[tableName];
|
|
150
|
+
if (!table) throw new Error(`Invalid table name ${tableName}.`);
|
|
151
|
+
return table;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
//#endregion
|
|
155
|
+
export { buildOutboxPlan, finalizeOutboxPayload };
|
|
156
|
+
//# sourceMappingURL=outbox-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox-builder.js","names":["drafts: OutboxMutationDraft[]","lookups: OutboxRefLookup[]","output: Record<string, unknown>"],"sources":["../../src/outbox/outbox-builder.ts"],"sourcesContent":["import { internalSchema } from \"../fragments/internal-fragment.schema\";\nimport type { MutationOperation } from \"../query/unit-of-work/unit-of-work\";\nimport type { AnySchema, AnyTable } from \"../schema/create\";\nimport { FragnoId, FragnoReference } from \"../schema/create\";\nimport type { OutboxRefLookup, OutboxPayload, OutboxMutation } from \"./outbox\";\nimport { encodeVersionstamp, versionstampToHex } from \"./outbox\";\n\nconst INTERNAL_TABLE_NAMES = new Set(Object.keys(internalSchema.tables));\n\ntype OutboxMutationDraft = OutboxMutation extends infer T\n ? T extends OutboxMutation\n ? Omit<T, \"versionstamp\"> & { versionstamp?: string }\n : never\n : never;\n\nexport type OutboxPlan = {\n drafts: OutboxMutationDraft[];\n lookups: OutboxRefLookup[];\n};\n\nexport function buildOutboxPlan(operations: MutationOperation<AnySchema>[]): OutboxPlan {\n const drafts: OutboxMutationDraft[] = [];\n const lookups: OutboxRefLookup[] = [];\n\n for (const op of operations) {\n if (op.type === \"check\") {\n continue;\n }\n\n if (isInternalMutation(op)) {\n continue;\n }\n\n const table = getTable(op.schema, op.table);\n const schemaName = op.namespace ?? \"\";\n const namespace = op.namespace ? op.namespace : undefined;\n const mutationIndex = drafts.length;\n\n if (op.type === \"create\") {\n drafts.push({\n op: \"create\",\n schema: schemaName,\n namespace,\n table: op.table,\n externalId: op.generatedExternalId,\n values: encodeOutboxValues({\n table,\n values: op.values,\n mutationIndex,\n namespace,\n lookups,\n }),\n });\n continue;\n }\n\n if (op.type === \"update\") {\n drafts.push({\n op: \"update\",\n schema: schemaName,\n namespace,\n table: op.table,\n externalId: getExternalId(op.id),\n set: encodeOutboxValues({\n table,\n values: op.set,\n mutationIndex,\n namespace,\n lookups,\n }),\n checkVersion: op.checkVersion && op.id instanceof FragnoId ? op.id.version : undefined,\n });\n continue;\n }\n\n if (op.type === \"delete\") {\n drafts.push({\n op: \"delete\",\n schema: schemaName,\n namespace,\n table: op.table,\n externalId: getExternalId(op.id),\n checkVersion: op.checkVersion && op.id instanceof FragnoId ? op.id.version : undefined,\n });\n }\n }\n\n return { drafts, lookups };\n}\n\nexport function finalizeOutboxPayload(plan: OutboxPlan, transactionVersion: bigint): OutboxPayload {\n const mutations: OutboxMutation[] = plan.drafts.map((draft, index) => {\n const versionstamp = versionstampToHex(encodeVersionstamp(transactionVersion, index));\n return { ...draft, versionstamp };\n });\n\n return {\n version: 1,\n mutations,\n };\n}\n\nfunction encodeOutboxValues(options: {\n table: AnyTable;\n values: Record<string, unknown>;\n mutationIndex: number;\n namespace?: string;\n lookups: OutboxRefLookup[];\n}): Record<string, unknown> {\n const { table, values, mutationIndex, namespace, lookups } = options;\n const output: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(values)) {\n if (value === undefined) {\n continue;\n }\n\n const column = table.columns[key];\n\n if (column?.role === \"reference\") {\n const resolved = resolveReferenceValue({\n value,\n mutationIndex,\n columnName: key,\n table,\n namespace,\n lookups,\n });\n output[key] = resolved;\n continue;\n }\n\n if (value instanceof FragnoId) {\n output[key] = value.externalId;\n continue;\n }\n\n output[key] = value;\n }\n\n return output;\n}\n\nfunction resolveReferenceValue(options: {\n value: unknown;\n mutationIndex: number;\n columnName: string;\n table: AnyTable;\n namespace?: string;\n lookups: OutboxRefLookup[];\n}): unknown {\n const { value, mutationIndex, columnName, table, namespace, lookups } = options;\n\n if (value === null) {\n return null;\n }\n\n if (value instanceof FragnoId) {\n return value.externalId;\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n if (value instanceof FragnoReference) {\n return createReferencePlaceholder({\n internalId: value.internalId,\n mutationIndex,\n columnName,\n table,\n namespace,\n lookups,\n });\n }\n\n if (typeof value === \"bigint\" || typeof value === \"number\") {\n return createReferencePlaceholder({\n internalId: value,\n mutationIndex,\n columnName,\n table,\n namespace,\n lookups,\n });\n }\n\n return value;\n}\n\nfunction createReferencePlaceholder(options: {\n internalId: bigint | number;\n mutationIndex: number;\n columnName: string;\n table: AnyTable;\n namespace?: string;\n lookups: OutboxRefLookup[];\n}): { __fragno_ref: string } {\n const { internalId, mutationIndex, columnName, table, namespace, lookups } = options;\n const key = `${mutationIndex}.${columnName}`;\n const referencedTable = resolveReferencedTable(table, columnName);\n\n lookups.push({\n key,\n internalId,\n table: referencedTable,\n namespace,\n });\n\n return { __fragno_ref: key };\n}\n\nfunction resolveReferencedTable(table: AnyTable, columnName: string): AnyTable {\n for (const relation of Object.values(table.relations)) {\n if (relation.on.some(([localColumn]) => localColumn === columnName)) {\n return relation.table;\n }\n }\n\n throw new Error(`Reference column ${columnName} not found in table ${table.name}`);\n}\n\nfunction getExternalId(id: FragnoId | string): string {\n return typeof id === \"string\" ? id : id.externalId;\n}\n\nfunction isInternalMutation(op: MutationOperation<AnySchema>): boolean {\n if (op.schema === internalSchema) {\n return true;\n }\n\n return op.namespace === \"\" && INTERNAL_TABLE_NAMES.has(op.table);\n}\n\nfunction getTable(schema: AnySchema, tableName: string): AnyTable {\n const table = schema.tables[tableName];\n if (!table) {\n throw new Error(`Invalid table name ${tableName}.`);\n }\n return table;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { AnySchema, FragnoId } from "../schema/create.js";
|
|
2
|
+
import { MutationOperation } from "../query/unit-of-work/unit-of-work.js";
|
|
3
|
+
|
|
4
|
+
//#region src/outbox/outbox.d.ts
|
|
5
|
+
type OutboxConfig = {
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
shouldInclude?: (operation: MutationOperation<AnySchema>) => boolean;
|
|
8
|
+
};
|
|
9
|
+
type OutboxPayload = {
|
|
10
|
+
version: 1;
|
|
11
|
+
mutations: OutboxMutation[];
|
|
12
|
+
};
|
|
13
|
+
type OutboxMutation = {
|
|
14
|
+
op: "create";
|
|
15
|
+
schema: string;
|
|
16
|
+
namespace?: string;
|
|
17
|
+
table: string;
|
|
18
|
+
externalId: string;
|
|
19
|
+
versionstamp: string;
|
|
20
|
+
values: Record<string, unknown>;
|
|
21
|
+
} | {
|
|
22
|
+
op: "update";
|
|
23
|
+
schema: string;
|
|
24
|
+
namespace?: string;
|
|
25
|
+
table: string;
|
|
26
|
+
externalId: string;
|
|
27
|
+
versionstamp: string;
|
|
28
|
+
set: Record<string, unknown>;
|
|
29
|
+
checkVersion?: number;
|
|
30
|
+
} | {
|
|
31
|
+
op: "delete";
|
|
32
|
+
schema: string;
|
|
33
|
+
namespace?: string;
|
|
34
|
+
table: string;
|
|
35
|
+
externalId: string;
|
|
36
|
+
versionstamp: string;
|
|
37
|
+
checkVersion?: number;
|
|
38
|
+
};
|
|
39
|
+
type OutboxRefMap = Record<string, string>;
|
|
40
|
+
type OutboxPayloadSerialized = {
|
|
41
|
+
json: unknown;
|
|
42
|
+
meta?: Record<string, unknown>;
|
|
43
|
+
};
|
|
44
|
+
type OutboxEntry = {
|
|
45
|
+
id: FragnoId;
|
|
46
|
+
versionstamp: string;
|
|
47
|
+
uowId: string;
|
|
48
|
+
payload: OutboxPayloadSerialized;
|
|
49
|
+
refMap?: OutboxRefMap;
|
|
50
|
+
createdAt: Date;
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
export { OutboxConfig, OutboxEntry, OutboxMutation, OutboxPayload, OutboxRefMap };
|
|
54
|
+
//# sourceMappingURL=outbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox.d.ts","names":[],"sources":["../../src/outbox/outbox.ts"],"sourcesContent":[],"mappings":";;;;KAGY,YAAA;;EAAA,aAAA,CAAA,EAAY,CAAA,SAAA,EAEM,iBAAA,CAAkB,SAAlB,CAAA,EAAiB,GAAA,OAAA;AAQ/C,CAAA;AAmCY,KAnCA,aAAA,GAmCY;EAEZ,OAAA,EAAA,CAAA;EAKA,SAAA,EAxCC,cAwCU,EAAA;CACjB;AAGK,KAzCC,cAAA,GAyCD;EACA,EAAA,EAAA,QAAA;EACE,MAAA,EAAA,MAAA;EAAI,SAAA,CAAA,EAAA,MAAA;;;;UAnCH;;;;;;;;OASH;;;;;;;;;;;KAaC,YAAA,GAAe;KAEf,uBAAA;;SAEH;;KAGG,WAAA;MACN;;;WAGK;WACA;aACE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/outbox/outbox.ts
|
|
2
|
+
function encodeVersionstamp(transactionVersion, userVersion) {
|
|
3
|
+
if (userVersion < 0 || userVersion > 65535) throw new Error(`Invalid outbox user version: ${userVersion}`);
|
|
4
|
+
const txBytes = bigintToBytes(transactionVersion, 10);
|
|
5
|
+
const userBytes = new Uint8Array(2);
|
|
6
|
+
userBytes[0] = userVersion >> 8 & 255;
|
|
7
|
+
userBytes[1] = userVersion & 255;
|
|
8
|
+
const combined = new Uint8Array(12);
|
|
9
|
+
combined.set(txBytes, 0);
|
|
10
|
+
combined.set(userBytes, 10);
|
|
11
|
+
return combined;
|
|
12
|
+
}
|
|
13
|
+
function versionstampToHex(bytes) {
|
|
14
|
+
let hex = "";
|
|
15
|
+
for (const byte of bytes) hex += byte.toString(16).padStart(2, "0");
|
|
16
|
+
return hex;
|
|
17
|
+
}
|
|
18
|
+
function parseOutboxVersionValue(value) {
|
|
19
|
+
if (typeof value === "bigint") return value;
|
|
20
|
+
if (typeof value === "number") return BigInt(value);
|
|
21
|
+
if (typeof value === "string") return BigInt(value);
|
|
22
|
+
throw new Error(`Invalid outbox version value: ${String(value)}`);
|
|
23
|
+
}
|
|
24
|
+
function bigintToBytes(value, length) {
|
|
25
|
+
const bytes = new Uint8Array(length);
|
|
26
|
+
let remaining = value;
|
|
27
|
+
for (let i = length - 1; i >= 0; i -= 1) {
|
|
28
|
+
bytes[i] = Number(remaining & 255n);
|
|
29
|
+
remaining >>= 8n;
|
|
30
|
+
}
|
|
31
|
+
if (remaining !== 0n) throw new Error(`Outbox version ${value} exceeds ${length * 8} bits`);
|
|
32
|
+
return bytes;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { encodeVersionstamp, parseOutboxVersionValue, versionstampToHex };
|
|
37
|
+
//# sourceMappingURL=outbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outbox.js","names":[],"sources":["../../src/outbox/outbox.ts"],"sourcesContent":["import type { MutationOperation } from \"../query/unit-of-work/unit-of-work\";\nimport type { AnySchema, AnyTable, FragnoId } from \"../schema/create\";\n\nexport type OutboxConfig = {\n enabled: boolean;\n shouldInclude?: (operation: MutationOperation<AnySchema>) => boolean;\n};\n\nexport type OutboxVersionstampStrategy =\n | \"update-returning\"\n | \"insert-on-conflict-returning\"\n | \"insert-on-duplicate-last-insert-id\";\n\nexport type OutboxPayload = {\n version: 1;\n mutations: OutboxMutation[];\n};\n\nexport type OutboxMutation =\n | {\n op: \"create\";\n schema: string;\n namespace?: string;\n table: string;\n externalId: string;\n versionstamp: string;\n values: Record<string, unknown>;\n }\n | {\n op: \"update\";\n schema: string;\n namespace?: string;\n table: string;\n externalId: string;\n versionstamp: string;\n set: Record<string, unknown>;\n checkVersion?: number;\n }\n | {\n op: \"delete\";\n schema: string;\n namespace?: string;\n table: string;\n externalId: string;\n versionstamp: string;\n checkVersion?: number;\n };\n\nexport type OutboxRefMap = Record<string, string>;\n\nexport type OutboxPayloadSerialized = {\n json: unknown;\n meta?: Record<string, unknown>;\n};\n\nexport type OutboxEntry = {\n id: FragnoId;\n versionstamp: string;\n uowId: string;\n payload: OutboxPayloadSerialized;\n refMap?: OutboxRefMap;\n createdAt: Date;\n};\n\nexport type OutboxRefLookup = {\n key: string;\n internalId: bigint | number;\n table: AnyTable;\n namespace?: string;\n};\n\nexport function encodeVersionstamp(transactionVersion: bigint, userVersion: number): Uint8Array {\n if (userVersion < 0 || userVersion > 0xffff) {\n throw new Error(`Invalid outbox user version: ${userVersion}`);\n }\n\n const txBytes = bigintToBytes(transactionVersion, 10);\n const userBytes = new Uint8Array(2);\n userBytes[0] = (userVersion >> 8) & 0xff;\n userBytes[1] = userVersion & 0xff;\n\n const combined = new Uint8Array(12);\n combined.set(txBytes, 0);\n combined.set(userBytes, 10);\n\n return combined;\n}\n\nexport function versionstampToHex(bytes: Uint8Array): string {\n let hex = \"\";\n for (const byte of bytes) {\n hex += byte.toString(16).padStart(2, \"0\");\n }\n return hex;\n}\n\nexport function hexToVersionstamp(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) {\n throw new Error(`Invalid versionstamp hex length: ${hex.length}`);\n }\n\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n bytes[i / 2] = Number.parseInt(hex.slice(i, i + 2), 16);\n }\n return bytes;\n}\n\nexport function parseOutboxVersionValue(value: unknown): bigint {\n if (typeof value === \"bigint\") {\n return value;\n }\n\n if (typeof value === \"number\") {\n return BigInt(value);\n }\n\n if (typeof value === \"string\") {\n return BigInt(value);\n }\n\n throw new Error(`Invalid outbox version value: ${String(value)}`);\n}\n\nfunction bigintToBytes(value: bigint, length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n let remaining = value;\n\n for (let i = length - 1; i >= 0; i -= 1) {\n bytes[i] = Number(remaining & 0xffn);\n remaining >>= 8n;\n }\n\n if (remaining !== 0n) {\n throw new Error(`Outbox version ${value} exceeds ${length * 8} bits`);\n }\n\n return bytes;\n}\n"],"mappings":";AAuEA,SAAgB,mBAAmB,oBAA4B,aAAiC;AAC9F,KAAI,cAAc,KAAK,cAAc,MACnC,OAAM,IAAI,MAAM,gCAAgC,cAAc;CAGhE,MAAM,UAAU,cAAc,oBAAoB,GAAG;CACrD,MAAM,YAAY,IAAI,WAAW,EAAE;AACnC,WAAU,KAAM,eAAe,IAAK;AACpC,WAAU,KAAK,cAAc;CAE7B,MAAM,WAAW,IAAI,WAAW,GAAG;AACnC,UAAS,IAAI,SAAS,EAAE;AACxB,UAAS,IAAI,WAAW,GAAG;AAE3B,QAAO;;AAGT,SAAgB,kBAAkB,OAA2B;CAC3D,IAAI,MAAM;AACV,MAAK,MAAM,QAAQ,MACjB,QAAO,KAAK,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI;AAE3C,QAAO;;AAeT,SAAgB,wBAAwB,OAAwB;AAC9D,KAAI,OAAO,UAAU,SACnB,QAAO;AAGT,KAAI,OAAO,UAAU,SACnB,QAAO,OAAO,MAAM;AAGtB,KAAI,OAAO,UAAU,SACnB,QAAO,OAAO,MAAM;AAGtB,OAAM,IAAI,MAAM,iCAAiC,OAAO,MAAM,GAAG;;AAGnE,SAAS,cAAc,OAAe,QAA4B;CAChE,MAAM,QAAQ,IAAI,WAAW,OAAO;CACpC,IAAI,YAAY;AAEhB,MAAK,IAAI,IAAI,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG;AACvC,QAAM,KAAK,OAAO,YAAY,KAAM;AACpC,gBAAc;;AAGhB,KAAI,cAAc,GAChB,OAAM,IAAI,MAAM,kBAAkB,MAAM,WAAW,SAAS,EAAE,OAAO;AAGvE,QAAO"}
|
|
@@ -12,16 +12,32 @@ import { createId } from "../id.js";
|
|
|
12
12
|
*
|
|
13
13
|
* @internal
|
|
14
14
|
*/
|
|
15
|
-
function generateRuntimeDefault(column) {
|
|
15
|
+
function generateRuntimeDefault(column, context = {}) {
|
|
16
16
|
if (!column.default) return;
|
|
17
17
|
if ("value" in column.default) return;
|
|
18
18
|
if ("dbSpecial" in column.default) return;
|
|
19
19
|
const runtime = column.default.runtime;
|
|
20
|
-
if (runtime === "cuid") return createId();
|
|
21
|
-
if (runtime === "now") return /* @__PURE__ */ new Date();
|
|
20
|
+
if (runtime === "cuid") return (context.createId ?? createId)();
|
|
21
|
+
if (runtime === "now") return (context.now ?? (() => /* @__PURE__ */ new Date()))();
|
|
22
22
|
if (typeof runtime === "function") return runtime();
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Generate a fallback value for database-level defaults.
|
|
26
|
+
*
|
|
27
|
+
* This is used by adapters that cannot rely on database DEFAULT constraints,
|
|
28
|
+
* such as the in-memory adapter.
|
|
29
|
+
*
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
function generateDatabaseDefault(column, context = {}) {
|
|
33
|
+
if (!column.default) return;
|
|
34
|
+
if ("value" in column.default) return column.default.value;
|
|
35
|
+
if ("dbSpecial" in column.default) {
|
|
36
|
+
if (column.default.dbSpecial === "now") return (context.now ?? (() => /* @__PURE__ */ new Date()))();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
24
40
|
|
|
25
41
|
//#endregion
|
|
26
|
-
export { generateRuntimeDefault };
|
|
42
|
+
export { generateDatabaseDefault, generateRuntimeDefault };
|
|
27
43
|
//# sourceMappingURL=column-defaults.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column-defaults.js","names":[],"sources":["../../src/query/column-defaults.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"column-defaults.js","names":[],"sources":["../../src/query/column-defaults.ts"],"sourcesContent":["import { createId } from \"../id\";\nimport type { AnyColumn } from \"../schema/create\";\n\nexport type RuntimeDefaultContext = {\n now?: () => Date;\n createId?: () => string;\n};\n\n/**\n * Generate a runtime default value for a column that has defaultTo$()\n *\n * Only generates values for runtime defaults (defaultTo$), NOT static defaults (defaultTo).\n * Static defaults should be handled by the database via DEFAULT constraints.\n *\n * @param column - The column with a default value configuration\n * @returns The generated default value, or undefined if the column has no runtime default\n *\n * @internal\n */\nexport function generateRuntimeDefault(\n column: AnyColumn,\n context: RuntimeDefaultContext = {},\n): unknown {\n // Check if column has a default value configuration\n if (!column.default) {\n return undefined;\n }\n\n // If it's a static default value (defaultTo), return undefined\n // as the database should handle this via DEFAULT constraint\n if (\"value\" in column.default) {\n return undefined;\n }\n\n // If it's a database-level special function (defaultTo(b => b.now())), return undefined\n // as the database should handle this via DEFAULT NOW() or equivalent\n if (\"dbSpecial\" in column.default) {\n return undefined;\n }\n\n // Handle runtime defaults (defaultTo$)\n const runtime = column.default.runtime;\n\n if (runtime === \"cuid\") {\n return (context.createId ?? createId)();\n }\n\n if (runtime === \"now\") {\n return (context.now ?? (() => new Date()))();\n }\n\n if (typeof runtime === \"function\") {\n return runtime();\n }\n\n return undefined;\n}\n\n/**\n * Generate a fallback value for database-level defaults.\n *\n * This is used by adapters that cannot rely on database DEFAULT constraints,\n * such as the in-memory adapter.\n *\n * @internal\n */\nexport function generateDatabaseDefault(\n column: AnyColumn,\n context: RuntimeDefaultContext = {},\n): unknown {\n if (!column.default) {\n return undefined;\n }\n\n if (\"value\" in column.default) {\n return column.default.value;\n }\n\n if (\"dbSpecial\" in column.default) {\n if (column.default.dbSpecial === \"now\") {\n return (context.now ?? (() => new Date()))();\n }\n return undefined;\n }\n\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAgB,uBACd,QACA,UAAiC,EAAE,EAC1B;AAET,KAAI,CAAC,OAAO,QACV;AAKF,KAAI,WAAW,OAAO,QACpB;AAKF,KAAI,eAAe,OAAO,QACxB;CAIF,MAAM,UAAU,OAAO,QAAQ;AAE/B,KAAI,YAAY,OACd,SAAQ,QAAQ,YAAY,WAAW;AAGzC,KAAI,YAAY,MACd,SAAQ,QAAQ,8BAAc,IAAI,MAAM,IAAI;AAG9C,KAAI,OAAO,YAAY,WACrB,QAAO,SAAS;;;;;;;;;;AAcpB,SAAgB,wBACd,QACA,UAAiC,EAAE,EAC1B;AACT,KAAI,CAAC,OAAO,QACV;AAGF,KAAI,WAAW,OAAO,QACpB,QAAO,OAAO,QAAQ;AAGxB,KAAI,eAAe,OAAO,SAAS;AACjC,MAAI,OAAO,QAAQ,cAAc,MAC/B,SAAQ,QAAQ,8BAAc,IAAI,MAAM,IAAI;AAE9C"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { DbInterval, DbIntervalInput, DbNow } from "./db-now.js";
|
|
1
2
|
import { AnyColumn, FragnoId, IdColumn } from "../schema/create.js";
|
|
2
3
|
|
|
3
4
|
//#region src/query/condition-builder.d.ts
|
|
5
|
+
type ConditionType = "compare" | "and" | "or" | "not";
|
|
4
6
|
type Condition = {
|
|
5
7
|
type: "compare";
|
|
6
8
|
a: AnyColumn;
|
|
@@ -30,12 +32,16 @@ type ConditionBuilder<Columns extends Record<string, AnyColumn>> = {
|
|
|
30
32
|
not: (v: Condition | boolean) => Condition | boolean;
|
|
31
33
|
isNull: (a: keyof Columns) => Condition;
|
|
32
34
|
isNotNull: (a: keyof Columns) => Condition;
|
|
35
|
+
now: () => DbNow;
|
|
36
|
+
interval: (input: DbIntervalInput) => DbInterval;
|
|
33
37
|
};
|
|
34
38
|
declare const stringOperators: readonly ["contains", "starts with", "ends with", "not contains", "not starts with", "not ends with"];
|
|
35
39
|
declare const arrayOperators: readonly ["in", "not in"];
|
|
36
40
|
declare const valueOperators: readonly ["=", "!=", ">", ">=", "<", "<=", "is", "is not"];
|
|
37
41
|
declare const operators: readonly ["=", "!=", ">", ">=", "<", "<=", "is", "is not", "in", "not in", "contains", "starts with", "ends with", "not contains", "not starts with", "not ends with"];
|
|
38
42
|
type Operator = (typeof operators)[number];
|
|
43
|
+
declare function createBuilder<Columns extends Record<string, AnyColumn>>(columns: Columns): ConditionBuilder<Columns>;
|
|
44
|
+
declare function buildCondition<T, Columns extends Record<string, AnyColumn>>(columns: Columns, input: (builder: ConditionBuilder<Columns>) => T): T;
|
|
39
45
|
//#endregion
|
|
40
|
-
export { Condition, ConditionBuilder };
|
|
46
|
+
export { Condition, ConditionBuilder, ConditionType, Operator, buildCondition, createBuilder, operators };
|
|
41
47
|
//# sourceMappingURL=condition-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"condition-builder.d.ts","names":[],"sources":["../../src/query/condition-builder.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"condition-builder.d.ts","names":[],"sources":["../../src/query/condition-builder.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { dbInterval, dbNow } from "./db-now.js";
|
|
2
|
+
|
|
1
3
|
//#region src/query/condition-builder.ts
|
|
2
4
|
const stringOperators = [
|
|
3
5
|
"contains",
|
|
@@ -49,6 +51,8 @@ function createBuilder(columns) {
|
|
|
49
51
|
};
|
|
50
52
|
builder.isNull = (a) => builder(a, "is", null);
|
|
51
53
|
builder.isNotNull = (a) => builder(a, "is not", null);
|
|
54
|
+
builder.now = () => dbNow();
|
|
55
|
+
builder.interval = (input) => dbInterval(input);
|
|
52
56
|
builder.not = (condition) => {
|
|
53
57
|
if (typeof condition === "boolean") return !condition;
|
|
54
58
|
return {
|
|
@@ -89,5 +93,5 @@ function buildCondition(columns, input) {
|
|
|
89
93
|
}
|
|
90
94
|
|
|
91
95
|
//#endregion
|
|
92
|
-
export { buildCondition };
|
|
96
|
+
export { buildCondition, createBuilder, operators };
|
|
93
97
|
//# sourceMappingURL=condition-builder.js.map
|