@yielded/auth-persistence-drizzle 0.1.0-beta.0 → 0.1.0-beta.12

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.
Files changed (291) hide show
  1. package/README.md +6 -1
  2. package/dist/D1.d.mts +155 -40
  3. package/dist/D1.mjs +10 -6
  4. package/dist/D1.mjs.map +1 -1
  5. package/dist/Libsql.d.mts +251 -129
  6. package/dist/Libsql.mjs +20 -21
  7. package/dist/Libsql.mjs.map +1 -1
  8. package/dist/Mysql2.d.mts +208 -56
  9. package/dist/Mysql2.mjs +13 -8
  10. package/dist/Mysql2.mjs.map +1 -1
  11. package/dist/Pglite.d.mts +209 -57
  12. package/dist/Pglite.mjs +13 -9
  13. package/dist/Pglite.mjs.map +1 -1
  14. package/dist/Postgres.d.mts +207 -55
  15. package/dist/Postgres.mjs +13 -9
  16. package/dist/Postgres.mjs.map +1 -1
  17. package/dist/SqliteBun.d.mts +249 -126
  18. package/dist/SqliteBun.mjs +20 -18
  19. package/dist/SqliteBun.mjs.map +1 -1
  20. package/dist/SqliteDo.d.mts +248 -158
  21. package/dist/SqliteDo.mjs +26 -44
  22. package/dist/SqliteDo.mjs.map +1 -1
  23. package/dist/SqliteNode.d.mts +247 -124
  24. package/dist/SqliteNode.mjs +20 -18
  25. package/dist/SqliteNode.mjs.map +1 -1
  26. package/dist/SqliteWasm.d.mts +251 -128
  27. package/dist/SqliteWasm.mjs +20 -18
  28. package/dist/SqliteWasm.mjs.map +1 -1
  29. package/dist/drizzle/D1BatchStatements.d.mts +1 -1
  30. package/dist/drizzle/D1BatchStatements.mjs.map +1 -1
  31. package/dist/drizzle/d1-database.d.mts +11 -0
  32. package/dist/drizzle/d1-database.mjs +8 -0
  33. package/dist/drizzle/d1-database.mjs.map +1 -0
  34. package/dist/drizzle/d1-emails.d.mts +8 -7
  35. package/dist/drizzle/d1-emails.mjs +7 -4
  36. package/dist/drizzle/d1-emails.mjs.map +1 -1
  37. package/dist/drizzle/d1-generated-statement.mjs.map +1 -1
  38. package/dist/drizzle/d1-identity.mjs +12 -9
  39. package/dist/drizzle/d1-identity.mjs.map +1 -1
  40. package/dist/drizzle/d1-oauth.d.mts +41 -10
  41. package/dist/drizzle/d1-oauth.mjs +8 -5
  42. package/dist/drizzle/d1-oauth.mjs.map +1 -1
  43. package/dist/drizzle/d1-passkey.d.mts +3 -14
  44. package/dist/drizzle/d1-passkey.mjs +2 -1
  45. package/dist/drizzle/d1-passkey.mjs.map +1 -1
  46. package/dist/drizzle/d1-password-prepared.d.mts +4 -3
  47. package/dist/drizzle/d1-password-prepared.mjs +3 -1
  48. package/dist/drizzle/d1-password-prepared.mjs.map +1 -1
  49. package/dist/drizzle/d1-passwords.d.mts +7 -6
  50. package/dist/drizzle/d1-passwords.mjs +5 -2
  51. package/dist/drizzle/d1-passwords.mjs.map +1 -1
  52. package/dist/drizzle/d1-phone.d.mts +3 -4
  53. package/dist/drizzle/d1-phone.mjs +2 -1
  54. package/dist/drizzle/d1-phone.mjs.map +1 -1
  55. package/dist/drizzle/d1-planning.d.mts +1 -1
  56. package/dist/drizzle/d1-proofs.d.mts +5 -4
  57. package/dist/drizzle/d1-proofs.mjs +3 -1
  58. package/dist/drizzle/d1-proofs.mjs.map +1 -1
  59. package/dist/drizzle/d1-sessions.d.mts +14 -13
  60. package/dist/drizzle/d1-sessions.mjs +15 -9
  61. package/dist/drizzle/d1-sessions.mjs.map +1 -1
  62. package/dist/drizzle/d1-totp.d.mts +3 -4
  63. package/dist/drizzle/d1-totp.mjs +2 -1
  64. package/dist/drizzle/d1-totp.mjs.map +1 -1
  65. package/dist/drizzle/email-registration.d.mts +1 -1
  66. package/dist/drizzle/email-registration.mjs +2 -1
  67. package/dist/drizzle/email-registration.mjs.map +1 -1
  68. package/dist/drizzle/email-target.d.mts +8 -7
  69. package/dist/drizzle/email-target.mjs +10 -10
  70. package/dist/drizzle/email-target.mjs.map +1 -1
  71. package/dist/drizzle/model.d.mts +2 -126
  72. package/dist/drizzle/model.mjs +2 -21
  73. package/dist/drizzle/model.mjs.map +1 -1
  74. package/dist/drizzle/mysql-database.d.mts +8 -0
  75. package/dist/drizzle/mysql-database.mjs +8 -0
  76. package/dist/drizzle/mysql-database.mjs.map +1 -0
  77. package/dist/drizzle/mysql-emails.d.mts +8 -7
  78. package/dist/drizzle/mysql-emails.mjs +12 -8
  79. package/dist/drizzle/mysql-emails.mjs.map +1 -1
  80. package/dist/drizzle/mysql-identity.mjs +12 -9
  81. package/dist/drizzle/mysql-identity.mjs.map +1 -1
  82. package/dist/drizzle/mysql-password-prepared.d.mts +4 -3
  83. package/dist/drizzle/mysql-password-prepared.mjs +6 -2
  84. package/dist/drizzle/mysql-password-prepared.mjs.map +1 -1
  85. package/dist/drizzle/mysql-passwords.d.mts +7 -5
  86. package/dist/drizzle/mysql-passwords.mjs +11 -7
  87. package/dist/drizzle/mysql-passwords.mjs.map +1 -1
  88. package/dist/drizzle/mysql-proofs.d.mts +4 -3
  89. package/dist/drizzle/mysql-proofs.mjs +8 -4
  90. package/dist/drizzle/mysql-proofs.mjs.map +1 -1
  91. package/dist/drizzle/mysql-sessions.d.mts +12 -11
  92. package/dist/drizzle/mysql-sessions.mjs +16 -12
  93. package/dist/drizzle/mysql-sessions.mjs.map +1 -1
  94. package/dist/drizzle/native-database.mjs +10 -0
  95. package/dist/drizzle/native-database.mjs.map +1 -0
  96. package/dist/drizzle/oauth-accounts.mjs +1 -1
  97. package/dist/drizzle/oauth-connected-access.mjs +14 -12
  98. package/dist/drizzle/oauth-connected-access.mjs.map +1 -1
  99. package/dist/drizzle/oauth-connected-custody.mjs +2 -2
  100. package/dist/drizzle/oauth-connected-drivers.mjs +11 -6
  101. package/dist/drizzle/oauth-connected-drivers.mjs.map +1 -1
  102. package/dist/drizzle/oauth-connected-flow.mjs +2 -2
  103. package/dist/drizzle/oauth-connected-input.mjs +14 -1
  104. package/dist/drizzle/oauth-connected-input.mjs.map +1 -1
  105. package/dist/drizzle/oauth-connected-maintenance.mjs +1 -1
  106. package/dist/drizzle/oauth-connected-management.mjs +2 -2
  107. package/dist/drizzle/oauth-connected-model.d.mts +17 -3
  108. package/dist/drizzle/oauth-connected-model.mjs.map +1 -1
  109. package/dist/drizzle/oauth-connected-settlement.mjs +51 -41
  110. package/dist/drizzle/oauth-connected-settlement.mjs.map +1 -1
  111. package/dist/drizzle/oauth-connected-sign-in.mjs +263 -0
  112. package/dist/drizzle/oauth-connected-sign-in.mjs.map +1 -0
  113. package/dist/drizzle/oauth-connected-state.d.mts +110 -2
  114. package/dist/drizzle/oauth-connected-state.mjs +9 -4
  115. package/dist/drizzle/oauth-connected-state.mjs.map +1 -1
  116. package/dist/drizzle/oauth-connected-target.d.mts +142 -15
  117. package/dist/drizzle/oauth-connected-target.mjs +9 -6
  118. package/dist/drizzle/oauth-connected-target.mjs.map +1 -1
  119. package/dist/drizzle/oauth-drivers.mjs +9 -7
  120. package/dist/drizzle/oauth-drivers.mjs.map +1 -1
  121. package/dist/drizzle/oauth-flow.d.mts +1 -1
  122. package/dist/drizzle/oauth-flow.mjs +1 -1
  123. package/dist/drizzle/oauth-input.mjs +1 -1
  124. package/dist/drizzle/oauth-model.d.mts +1 -1
  125. package/dist/drizzle/oauth-owner.d.mts +1 -1
  126. package/dist/drizzle/oauth-registration.d.mts +2 -2
  127. package/dist/drizzle/oauth-registration.mjs +1 -1
  128. package/dist/drizzle/oauth-state.mjs +5 -4
  129. package/dist/drizzle/oauth-state.mjs.map +1 -1
  130. package/dist/drizzle/oauth-target.d.mts +14 -13
  131. package/dist/drizzle/oauth-target.mjs +14 -13
  132. package/dist/drizzle/oauth-target.mjs.map +1 -1
  133. package/dist/drizzle/passkey-drivers.mjs +8 -6
  134. package/dist/drizzle/passkey-drivers.mjs.map +1 -1
  135. package/dist/drizzle/passkey-write-drivers.mjs +5 -3
  136. package/dist/drizzle/passkey-write-drivers.mjs.map +1 -1
  137. package/dist/drizzle/passkey-write-target.d.mts +1 -1
  138. package/dist/drizzle/password-prepared-sql.mjs +2 -1
  139. package/dist/drizzle/password-prepared-sql.mjs.map +1 -1
  140. package/dist/drizzle/password-prepared-state.mjs +1 -1
  141. package/dist/drizzle/password-prepared-target.d.mts +4 -3
  142. package/dist/drizzle/password-prepared-target.mjs +4 -3
  143. package/dist/drizzle/password-prepared-target.mjs.map +1 -1
  144. package/dist/drizzle/password-registration.mjs +2 -1
  145. package/dist/drizzle/password-registration.mjs.map +1 -1
  146. package/dist/drizzle/password-target.d.mts +6 -5
  147. package/dist/drizzle/password-target.mjs +8 -8
  148. package/dist/drizzle/password-target.mjs.map +1 -1
  149. package/dist/drizzle/pg-database.d.mts +9 -0
  150. package/dist/drizzle/pg-database.mjs +8 -0
  151. package/dist/drizzle/pg-database.mjs.map +1 -0
  152. package/dist/drizzle/pg-emails.d.mts +8 -7
  153. package/dist/drizzle/pg-emails.mjs +12 -8
  154. package/dist/drizzle/pg-emails.mjs.map +1 -1
  155. package/dist/drizzle/pg-identity.mjs +92 -0
  156. package/dist/drizzle/pg-identity.mjs.map +1 -0
  157. package/dist/drizzle/pg-password-prepared.d.mts +4 -3
  158. package/dist/drizzle/pg-password-prepared.mjs +6 -2
  159. package/dist/drizzle/pg-password-prepared.mjs.map +1 -1
  160. package/dist/drizzle/pg-passwords.d.mts +7 -5
  161. package/dist/drizzle/pg-passwords.mjs +11 -7
  162. package/dist/drizzle/pg-passwords.mjs.map +1 -1
  163. package/dist/drizzle/pg-proofs.d.mts +4 -3
  164. package/dist/drizzle/pg-proofs.mjs +8 -4
  165. package/dist/drizzle/pg-proofs.mjs.map +1 -1
  166. package/dist/drizzle/pg-sessions.d.mts +12 -11
  167. package/dist/drizzle/pg-sessions.mjs +16 -12
  168. package/dist/drizzle/pg-sessions.mjs.map +1 -1
  169. package/dist/drizzle/phone-model.d.mts +1 -1
  170. package/dist/drizzle/phone-target.d.mts +5 -4
  171. package/dist/drizzle/phone-target.mjs +12 -11
  172. package/dist/drizzle/phone-target.mjs.map +1 -1
  173. package/dist/drizzle/proof-target.d.mts +4 -3
  174. package/dist/drizzle/proof-target.mjs +5 -5
  175. package/dist/drizzle/proof-target.mjs.map +1 -1
  176. package/dist/drizzle/session-sql.d.mts +1 -0
  177. package/dist/drizzle/session-target.d.mts +11 -9
  178. package/dist/drizzle/session-target.mjs +11 -11
  179. package/dist/drizzle/session-target.mjs.map +1 -1
  180. package/dist/drizzle/sqlite-emails.mjs +9 -5
  181. package/dist/drizzle/sqlite-emails.mjs.map +1 -1
  182. package/dist/drizzle/sqlite-identity.mjs +14 -11
  183. package/dist/drizzle/sqlite-identity.mjs.map +1 -1
  184. package/dist/drizzle/sqlite-password-prepared.mjs +7 -3
  185. package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -1
  186. package/dist/drizzle/sqlite-passwords.mjs +10 -6
  187. package/dist/drizzle/sqlite-passwords.mjs.map +1 -1
  188. package/dist/drizzle/sqlite-proofs.mjs +7 -3
  189. package/dist/drizzle/sqlite-proofs.mjs.map +1 -1
  190. package/dist/drizzle/sqlite-sessions.mjs +16 -12
  191. package/dist/drizzle/sqlite-sessions.mjs.map +1 -1
  192. package/dist/drizzle/standalone-guard.d.mts +2 -0
  193. package/dist/drizzle/standalone-guard.mjs +8 -4
  194. package/dist/drizzle/standalone-guard.mjs.map +1 -1
  195. package/dist/drizzle/totp-model.d.mts +1 -1
  196. package/dist/drizzle/totp-target.d.mts +5 -4
  197. package/dist/drizzle/totp-target.mjs +31 -28
  198. package/dist/drizzle/totp-target.mjs.map +1 -1
  199. package/dist/drizzle/transaction-mysql.mjs +1 -1
  200. package/dist/drizzle/transaction-mysql.mjs.map +1 -1
  201. package/dist/index.d.mts +2 -4
  202. package/dist/index.mjs +2 -4
  203. package/dist/internal/drizzle-postgres.mjs.map +1 -1
  204. package/dist/internal/drizzle-sqlite.mjs.map +1 -1
  205. package/package.json +1 -1
  206. package/src/D1.ts +37 -26
  207. package/src/Libsql.ts +45 -61
  208. package/src/Mysql2.ts +39 -35
  209. package/src/Pglite.ts +48 -30
  210. package/src/Postgres.ts +48 -30
  211. package/src/SqliteBun.ts +59 -68
  212. package/src/SqliteDo.ts +61 -274
  213. package/src/SqliteNode.ts +56 -66
  214. package/src/SqliteWasm.ts +56 -66
  215. package/src/drizzle/D1BatchStatements.ts +1 -1
  216. package/src/drizzle/d1-database.ts +10 -0
  217. package/src/drizzle/d1-emails.ts +86 -88
  218. package/src/drizzle/d1-generated-statement.ts +1 -1
  219. package/src/drizzle/d1-identity.ts +17 -20
  220. package/src/drizzle/d1-oauth.ts +19 -8
  221. package/src/drizzle/d1-passkey.ts +5 -1
  222. package/src/drizzle/d1-password-prepared.ts +40 -42
  223. package/src/drizzle/d1-passwords.ts +76 -80
  224. package/src/drizzle/d1-phone.ts +5 -1
  225. package/src/drizzle/d1-proofs.ts +31 -34
  226. package/src/drizzle/d1-sessions.ts +53 -40
  227. package/src/drizzle/d1-totp.ts +5 -1
  228. package/src/drizzle/email-registration.ts +6 -2
  229. package/src/drizzle/email-target.ts +18 -20
  230. package/src/drizzle/model.ts +1 -208
  231. package/src/drizzle/mysql-database.ts +8 -0
  232. package/src/drizzle/mysql-emails.ts +29 -17
  233. package/src/drizzle/mysql-identity.ts +18 -21
  234. package/src/drizzle/mysql-password-prepared.ts +11 -9
  235. package/src/drizzle/mysql-passwords.ts +22 -10
  236. package/src/drizzle/mysql-proofs.ts +17 -6
  237. package/src/drizzle/mysql-sessions.ts +41 -18
  238. package/src/drizzle/native-database.ts +22 -0
  239. package/src/drizzle/oauth-connected-access.ts +8 -1
  240. package/src/drizzle/oauth-connected-drivers.ts +21 -6
  241. package/src/drizzle/oauth-connected-input.ts +13 -0
  242. package/src/drizzle/oauth-connected-model.ts +17 -0
  243. package/src/drizzle/oauth-connected-settlement.ts +65 -42
  244. package/src/drizzle/oauth-connected-sign-in.ts +438 -0
  245. package/src/drizzle/oauth-connected-state.ts +19 -7
  246. package/src/drizzle/oauth-connected-target.ts +26 -18
  247. package/src/drizzle/oauth-drivers.ts +26 -10
  248. package/src/drizzle/oauth-state.ts +5 -4
  249. package/src/drizzle/oauth-target.ts +31 -43
  250. package/src/drizzle/passkey-drivers.ts +21 -13
  251. package/src/drizzle/passkey-write-drivers.ts +11 -6
  252. package/src/drizzle/password-prepared-sql.ts +2 -4
  253. package/src/drizzle/password-prepared-target.ts +10 -7
  254. package/src/drizzle/password-registration.ts +7 -8
  255. package/src/drizzle/password-target.ts +20 -19
  256. package/src/drizzle/pg-database.ts +10 -0
  257. package/src/drizzle/pg-emails.ts +29 -17
  258. package/src/drizzle/pg-identity.ts +297 -0
  259. package/src/drizzle/pg-password-prepared.ts +11 -9
  260. package/src/drizzle/pg-passwords.ts +22 -10
  261. package/src/drizzle/pg-proofs.ts +17 -6
  262. package/src/drizzle/pg-sessions.ts +41 -18
  263. package/src/drizzle/phone-target.ts +23 -18
  264. package/src/drizzle/proof-target.ts +10 -13
  265. package/src/drizzle/session-target.ts +33 -51
  266. package/src/drizzle/sqlite-emails.ts +31 -14
  267. package/src/drizzle/sqlite-identity.ts +22 -42
  268. package/src/drizzle/sqlite-password-prepared.ts +24 -10
  269. package/src/drizzle/sqlite-passwords.ts +30 -16
  270. package/src/drizzle/sqlite-proofs.ts +29 -6
  271. package/src/drizzle/sqlite-sessions.ts +50 -24
  272. package/src/drizzle/standalone-guard.ts +19 -7
  273. package/src/drizzle/totp-target.ts +62 -61
  274. package/src/drizzle/transaction-mysql.ts +1 -1
  275. package/src/index.ts +0 -24
  276. package/src/internal/drizzle-postgres.ts +1 -1
  277. package/src/internal/drizzle-sqlite.ts +1 -1
  278. package/dist/drizzle/d1-identity.d.mts +0 -30
  279. package/dist/drizzle/mysql-identity.d.mts +0 -21
  280. package/dist/drizzle/mysql.d.mts +0 -69
  281. package/dist/drizzle/mysql.mjs +0 -218
  282. package/dist/drizzle/mysql.mjs.map +0 -1
  283. package/dist/drizzle/pg.d.mts +0 -80
  284. package/dist/drizzle/pg.mjs +0 -289
  285. package/dist/drizzle/pg.mjs.map +0 -1
  286. package/dist/drizzle/sqlite.d.mts +0 -77
  287. package/dist/drizzle/sqlite.mjs +0 -217
  288. package/dist/drizzle/sqlite.mjs.map +0 -1
  289. package/src/drizzle/mysql.ts +0 -687
  290. package/src/drizzle/pg.ts +0 -984
  291. package/src/drizzle/sqlite.ts +0 -705
@@ -6,7 +6,7 @@ import type { EffectPgDatabase as PgliteDatabase } from "drizzle-orm/effect-pgli
6
6
  import type { EffectPgDatabase as PostgresDatabase } from "drizzle-orm/effect-postgres";
7
7
  import type { AnyPgTable } from "drizzle-orm/pg-core";
8
8
  import { Effect, Context } from "effect";
9
- import type { SqlError } from "effect/unstable/sql/SqlError";
9
+ import type { SqlError } from "effect/sql/SqlError";
10
10
 
11
11
  import type {
12
12
  EmailAddressMapping,
@@ -14,6 +14,7 @@ import type {
14
14
  EmailSignInMapping,
15
15
  } from "./email-model";
16
16
  import type { EmailRegistrationAuthority } from "./email-registration";
17
+ import { CurrentEmailSql } from "./email-sql";
17
18
  import type { EmailSqlQuery } from "./email-sql";
18
19
  import {
19
20
  coordinateTargetEmailAddress,
@@ -23,9 +24,16 @@ import {
23
24
  makeTargetEmailSignInServices,
24
25
  sqlClientEmailStandaloneGuard,
25
26
  } from "./email-target";
27
+ import { nativeDatabase } from "./native-database";
28
+ import { Database as DatabaseService } from "./pg-database";
26
29
  import type { ProofPersistenceMapping } from "./proof-model";
27
30
  import type { ProofSqlQuery } from "./proof-sql";
28
31
  import { sqlClientProofStandaloneGuard } from "./proof-target";
32
+ import {
33
+ type TransactionService,
34
+ acquireTransactionService,
35
+ transactionService,
36
+ } from "./standalone-guard";
29
37
  import type { SuppliedService } from "./SuppliedService";
30
38
 
31
39
  type Database = PostgresDatabase<AnyRelations> | PgliteDatabase<AnyRelations>;
@@ -45,15 +53,15 @@ type ProofMapping = ProofPersistenceMapping<
45
53
  any
46
54
  >;
47
55
 
48
- const configuration = (database: Database) => ({
56
+ const configuration = (service: TransactionService | undefined) => ({
49
57
  mode: "interactive" as const,
50
58
  locking: true,
51
- standaloneGuard: sqlClientEmailStandaloneGuard(database),
59
+ standaloneGuard: sqlClientEmailStandaloneGuard(service),
52
60
  generatedSubjectRows: (query: EmailSqlQuery) => query.returning(),
53
61
  proof: {
54
62
  mode: "interactive" as const,
55
63
  locking: true,
56
- standaloneGuard: sqlClientProofStandaloneGuard(database),
64
+ standaloneGuard: sqlClientProofStandaloneGuard(service),
57
65
  insertIfAbsent: (query: ProofSqlQuery) => query.onConflictDoNothing(),
58
66
  },
59
67
  });
@@ -64,9 +72,12 @@ export const makePgEmailSignInServices = <
64
72
  C extends AnyPgTable,
65
73
  NativeId,
66
74
  >(
67
- database: Database,
68
75
  mapping: EmailSignInMapping<S, I, C, NativeId>,
69
- ) => makeTargetEmailSignInServices(database, mapping, configuration(database));
76
+ ) =>
77
+ Effect.flatMap(
78
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
79
+ (configuration) => makeTargetEmailSignInServices(mapping, configuration),
80
+ ).pipe(Effect.provideServiceEffect(CurrentEmailSql, nativeDatabase(DatabaseService)));
70
81
 
71
82
  export const makePgEmailAddressServices = <
72
83
  S extends AnyPgTable,
@@ -76,10 +87,13 @@ export const makePgEmailAddressServices = <
76
87
  M extends AnyPgTable,
77
88
  NativeId,
78
89
  >(
79
- database: Database,
80
90
  mapping: EmailAddressMapping<S, I, C, AC, M, NativeId>,
81
91
  proofMapping: ProofMapping,
82
- ) => makeTargetEmailAddressServices(database, mapping, proofMapping, configuration(database));
92
+ ) =>
93
+ Effect.flatMap(
94
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
95
+ (configuration) => makeTargetEmailAddressServices(mapping, proofMapping, configuration),
96
+ ).pipe(Effect.provideServiceEffect(CurrentEmailSql, nativeDatabase(DatabaseService)));
83
97
 
84
98
  export function coordinatePgEmailAddress<
85
99
  D extends Database,
@@ -170,7 +184,7 @@ export function coordinatePgEmailAddress<
170
184
  database,
171
185
  options.mapping,
172
186
  options.proofMapping,
173
- configuration(database),
187
+ configuration(transactionService(database)),
174
188
  (
175
189
  transaction: TransactionOf<D>,
176
190
  services: { readonly emailAddressPersistence: EmailAddressPersistence["Service"] },
@@ -195,16 +209,14 @@ export const makePgEmailRegistrationServices = <
195
209
  Rq extends AnyPgTable,
196
210
  NativeId,
197
211
  >(
198
- database: Database,
199
212
  mapping: EmailRegistrationMapping<Registration, S, I, C, AC, Rq, NativeId>,
200
213
  proofMapping: ProofMapping,
201
214
  ) =>
202
- makeTargetEmailRegistrationServices<Registration>(
203
- database,
204
- mapping,
205
- proofMapping,
206
- configuration(database),
207
- );
215
+ Effect.flatMap(
216
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
217
+ (configuration) =>
218
+ makeTargetEmailRegistrationServices<Registration>(mapping, proofMapping, configuration),
219
+ ).pipe(Effect.provideServiceEffect(CurrentEmailSql, nativeDatabase(DatabaseService)));
208
220
 
209
221
  export function coordinatePgEmailRegistration<
210
222
  TargetId,
@@ -304,7 +316,7 @@ export function coordinatePgEmailRegistration<
304
316
  database,
305
317
  options.mapping,
306
318
  options.proofMapping,
307
- configuration(database),
319
+ configuration(transactionService(database)),
308
320
  (
309
321
  transaction: TransactionOf<D>,
310
322
  services: { readonly registrationAuthority: EmailRegistrationAuthority<Registration> },
@@ -0,0 +1,297 @@
1
+ import {
2
+ ExternalIdentityMutation,
3
+ IdentityConflict,
4
+ IdentityUnavailable,
5
+ SubjectProvisioned,
6
+ type ExternalIdentity,
7
+ SubjectProvisioner,
8
+ type SubjectProvisioningInput,
9
+ } from "@yielded/auth/Identity";
10
+ import { reportPersistenceFailure } from "@yielded/auth/Persistence";
11
+ import type { SubjectId } from "@yielded/auth/Schema";
12
+ /* oxlint-disable no-explicit-any -- Drizzle's generic query builders lose the concrete consumer table through a runtime column map. Assertions stay in this adapter. */
13
+ import { and, eq } from "drizzle-orm";
14
+ import type { EffectPgDatabase as PgDatabase } from "drizzle-orm/effect-postgres";
15
+ import { type AnyPgTable, type PgColumn } from "drizzle-orm/pg-core";
16
+ import { Cause, Effect, Schema } from "effect";
17
+
18
+ import {
19
+ column,
20
+ PersistenceMappingError,
21
+ isMappedConstraintConflict,
22
+ provisioningFingerprint,
23
+ type ExternalIdentityTables,
24
+ type IdentityTables,
25
+ type SubjectProvisioningTables,
26
+ } from "./model";
27
+ import { Database as DatabaseService } from "./pg-database";
28
+
29
+ type RuntimeDatabase = PgDatabase<any>;
30
+
31
+ const identityUnavailable = () => IdentityUnavailable.make();
32
+ const isIdentityFailure = Schema.is(Schema.Union([IdentityConflict, IdentityUnavailable]));
33
+
34
+ const mapIdentityFailure = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
35
+ reportPersistenceFailure(effect, isIdentityFailure).pipe(
36
+ Effect.catchCause((cause) =>
37
+ Effect.failCause(
38
+ Cause.map(cause, (error) => (isIdentityFailure(error) ? error : identityUnavailable())),
39
+ ),
40
+ ),
41
+ );
42
+
43
+ export const makePgSubjectProvisioningServices = Effect.fnUntraced(function* <
44
+ Subject extends AnyPgTable,
45
+ Identifier extends AnyPgTable,
46
+ Request extends AnyPgTable,
47
+ NativeId,
48
+ >(mapping: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>) {
49
+ const database = yield* DatabaseService;
50
+
51
+ const db = database as RuntimeDatabase;
52
+ const requestTable = mapping.provisioningRequest.table;
53
+ const requestIdColumn = column(requestTable, mapping.provisioningRequest.requestId);
54
+ const requestFingerprintColumn = column(requestTable, mapping.provisioningRequest.fingerprint);
55
+ const requestSubjectColumn = column(requestTable, mapping.provisioningRequest.subjectId);
56
+ const identifierTable = mapping.identifier.table;
57
+ const identifierNamespaceColumn = column(identifierTable, mapping.identifier.namespace);
58
+ const identifierValueColumn = column(identifierTable, mapping.identifier.value);
59
+
60
+ const findReceipt = Effect.fn("DrizzlePgIdentity.findReceipt")(function* (requestId: string) {
61
+ const rows = yield* db
62
+ .select({
63
+ fingerprint: requestFingerprintColumn as PgColumn,
64
+ subjectId: requestSubjectColumn as PgColumn,
65
+ })
66
+ .from(requestTable as any)
67
+ .where(eq(requestIdColumn, requestId))
68
+ .limit(1);
69
+
70
+ return rows[0];
71
+ });
72
+
73
+ const provision = Effect.fn("DrizzlePgIdentity.provision")(function* (
74
+ input: SubjectProvisioningInput,
75
+ ) {
76
+ const fingerprint = provisioningFingerprint(input);
77
+ const existing = yield* findReceipt(input.requestId);
78
+
79
+ if (existing !== undefined) {
80
+ if (existing.fingerprint !== fingerprint) return yield* IdentityConflict.make();
81
+ const id = yield* mapping.subjectId.toSubject(existing.subjectId as NativeId);
82
+
83
+ return SubjectProvisioned.make({ subjectId: id });
84
+ }
85
+
86
+ const attempt = db.transaction((tx) =>
87
+ Effect.gen(function* () {
88
+ const allocated =
89
+ mapping.subject.allocateId === undefined ? undefined : yield* mapping.subject.allocateId;
90
+
91
+ const inserted = yield* tx
92
+ .insert(mapping.subject.table as any)
93
+ .values(mapping.subject.encodeInsert(input, allocated) as any)
94
+ .returning({ id: column(mapping.subject.table, mapping.subject.id) as PgColumn });
95
+
96
+ const nativeId = (inserted[0]?.id ?? allocated) as NativeId | undefined;
97
+
98
+ if (nativeId === undefined) {
99
+ return yield* PersistenceMappingError.make({
100
+ operation: "provisionSubject.generatedId",
101
+ cause: new Error("subject insert did not return its native id"),
102
+ });
103
+ }
104
+ if (input.identifier !== undefined) {
105
+ yield* tx
106
+ .insert(identifierTable as any)
107
+ .values(
108
+ mapping.identifier.encodeInsert(input.identifier, nativeId, input.verifiedAt) as any,
109
+ );
110
+ }
111
+ yield* tx
112
+ .insert(requestTable as any)
113
+ .values(
114
+ mapping.provisioningRequest.encodeInsert(input.requestId, fingerprint, nativeId) as any,
115
+ );
116
+
117
+ return nativeId;
118
+ }),
119
+ );
120
+
121
+ const nativeId = yield* attempt.pipe(
122
+ Effect.catchCause(
123
+ (
124
+ cause,
125
+ ): Effect.Effect<
126
+ NativeId,
127
+ | Effect.Error<typeof attempt>
128
+ | Effect.Error<ReturnType<typeof findReceipt>>
129
+ | IdentityConflict
130
+ > => {
131
+ if (
132
+ cause.reasons.length === 0 ||
133
+ !cause.reasons.every(
134
+ (reason) =>
135
+ Cause.isFailReason(reason) &&
136
+ isMappedConstraintConflict(mapping.isConstraintConflict, reason.error),
137
+ )
138
+ )
139
+ return Effect.failCause(cause);
140
+
141
+ return findReceipt(input.requestId).pipe(
142
+ Effect.flatMap((receipt) => {
143
+ if (receipt !== undefined && receipt.fingerprint === fingerprint) {
144
+ return Effect.succeed(receipt.subjectId as NativeId);
145
+ }
146
+ if (input.identifier === undefined) return IdentityConflict.make();
147
+
148
+ return db
149
+ .select({
150
+ subjectId: column(identifierTable, mapping.identifier.subjectId) as PgColumn,
151
+ })
152
+ .from(identifierTable as any)
153
+ .where(
154
+ and(
155
+ eq(identifierNamespaceColumn, input.identifier.namespace),
156
+ eq(identifierValueColumn, input.identifier.value),
157
+ ),
158
+ )
159
+ .limit(1)
160
+ .pipe(Effect.flatMap(() => IdentityConflict.make()));
161
+ }),
162
+ );
163
+ },
164
+ ),
165
+ );
166
+
167
+ const subjectId = yield* mapping.subjectId.toSubject(nativeId);
168
+
169
+ return SubjectProvisioned.make({ subjectId });
170
+ }, mapIdentityFailure);
171
+
172
+ return {
173
+ subjectProvisioner: SubjectProvisioner.of({ provision }),
174
+ } as const;
175
+ });
176
+
177
+ export const makePgExternalIdentityServices = Effect.fnUntraced(function* <
178
+ Subject extends AnyPgTable,
179
+ External extends AnyPgTable,
180
+ NativeId,
181
+ >(mapping: ExternalIdentityTables<Subject, External, NativeId>) {
182
+ const database = yield* DatabaseService;
183
+
184
+ const db = database as RuntimeDatabase;
185
+ const externalTable = mapping.externalIdentity.table;
186
+
187
+ const externalProviderColumn = column(
188
+ externalTable,
189
+ mapping.externalIdentity.provider,
190
+ ) as PgColumn;
191
+
192
+ const externalIssuerColumn = column(externalTable, mapping.externalIdentity.issuer) as PgColumn;
193
+ const externalSubjectColumn = column(externalTable, mapping.externalIdentity.subject) as PgColumn;
194
+
195
+ const externalSubjectIdColumn = column(
196
+ externalTable,
197
+ mapping.externalIdentity.subjectId,
198
+ ) as PgColumn;
199
+
200
+ const subjectIdColumn = column(mapping.subject.table, mapping.subject.id) as PgColumn;
201
+ const subjectStatusColumn = column(mapping.subject.table, mapping.subject.status) as PgColumn;
202
+
203
+ const bind = Effect.fn("DrizzlePgIdentity.bindExternalIdentity")(function* (
204
+ subjectId: SubjectId,
205
+ identity: ExternalIdentity,
206
+ ) {
207
+ const nativeId = yield* mapping.subjectId.toNative(subjectId);
208
+
209
+ const decision = yield* db
210
+ .transaction((tx) =>
211
+ Effect.gen(function* () {
212
+ const subjects = yield* tx
213
+ .select({ status: subjectStatusColumn })
214
+ .from(mapping.subject.table as any)
215
+ .where(eq(subjectIdColumn, nativeId))
216
+ .for("update")
217
+ .limit(1);
218
+
219
+ if (subjects[0] === undefined || !mapping.subject.isActiveStatus(subjects[0].status))
220
+ return { _tag: "conflict" } as const;
221
+
222
+ const links = yield* tx
223
+ .select({ subjectId: externalSubjectIdColumn })
224
+ .from(externalTable as any)
225
+ .where(
226
+ and(
227
+ eq(externalProviderColumn, identity.provider),
228
+ eq(externalIssuerColumn, identity.issuer),
229
+ eq(externalSubjectColumn, identity.subject),
230
+ ),
231
+ )
232
+ .for("update")
233
+ .limit(1);
234
+
235
+ if (links[0] !== undefined)
236
+ return mapping.subjectId.equals(links[0].subjectId as NativeId, nativeId)
237
+ ? ({ _tag: "bound" } as const)
238
+ : ({ _tag: "conflict" } as const);
239
+ yield* tx
240
+ .insert(externalTable as any)
241
+ .values(mapping.externalIdentity.encodeInsert(identity, nativeId) as any);
242
+
243
+ return { _tag: "bound" } as const;
244
+ }),
245
+ )
246
+ .pipe(
247
+ Effect.catchCause((cause) => {
248
+ if (
249
+ cause.reasons.length === 0 ||
250
+ !cause.reasons.every(
251
+ (reason) =>
252
+ Cause.isFailReason(reason) &&
253
+ isMappedConstraintConflict(mapping.isConstraintConflict, reason.error),
254
+ )
255
+ )
256
+ return Effect.failCause(cause);
257
+
258
+ return db
259
+ .select({ subjectId: externalSubjectIdColumn })
260
+ .from(externalTable as any)
261
+ .where(
262
+ and(
263
+ eq(externalProviderColumn, identity.provider),
264
+ eq(externalIssuerColumn, identity.issuer),
265
+ eq(externalSubjectColumn, identity.subject),
266
+ ),
267
+ )
268
+ .limit(1)
269
+ .pipe(
270
+ Effect.map((rows) =>
271
+ rows[0] !== undefined &&
272
+ mapping.subjectId.equals(rows[0].subjectId as NativeId, nativeId)
273
+ ? ({ _tag: "bound" } as const)
274
+ : ({ _tag: "conflict" } as const),
275
+ ),
276
+ );
277
+ }),
278
+ );
279
+
280
+ if (decision._tag === "conflict") return yield* IdentityConflict.make();
281
+ }, mapIdentityFailure);
282
+
283
+ return { externalIdentityMutation: ExternalIdentityMutation.of({ bind }) } as const;
284
+ });
285
+
286
+ export const makePgIdentityServices = Effect.fnUntraced(function* <
287
+ Subject extends AnyPgTable,
288
+ Identifier extends AnyPgTable,
289
+ External extends AnyPgTable,
290
+ Request extends AnyPgTable,
291
+ NativeId,
292
+ >(mapping: IdentityTables<Subject, Identifier, External, Request, NativeId>) {
293
+ return {
294
+ ...(yield* makePgSubjectProvisioningServices(mapping)),
295
+ ...(yield* makePgExternalIdentityServices(mapping)),
296
+ };
297
+ });
@@ -5,8 +5,9 @@ import type { EffectPgDatabase as PgliteDatabase } from "drizzle-orm/effect-pgli
5
5
  import type { EffectPgDatabase as PostgresDatabase } from "drizzle-orm/effect-postgres";
6
6
  import type { AnyPgTable } from "drizzle-orm/pg-core";
7
7
  import { Effect, Context } from "effect";
8
- import type { SqlError } from "effect/unstable/sql/SqlError";
8
+ import type { SqlError } from "effect/sql/SqlError";
9
9
 
10
+ import { nativeDatabase } from "./native-database";
10
11
  import type {
11
12
  PasswordPreparedPersistenceMapping,
12
13
  PasswordPreparedProofMapping,
@@ -15,7 +16,10 @@ import {
15
16
  makeTargetPasswordPreparedPersistenceServices,
16
17
  coordinateTargetPasswordPreparedPersistence,
17
18
  } from "./password-prepared-target";
19
+ import { CurrentPasswordSql } from "./password-sql";
20
+ import { Database as DatabaseService } from "./pg-database";
18
21
  import { pgPasswordConfiguration as configuration } from "./pg-passwords";
22
+ import { acquireTransactionService, transactionService } from "./standalone-guard";
19
23
  import type { SuppliedService } from "./SuppliedService";
20
24
  type Database = PostgresDatabase<AnyRelations> | PgliteDatabase<AnyRelations>;
21
25
  type TransactionOf<D extends Database> = Parameters<Parameters<D["transaction"]>[0]>[0];
@@ -40,16 +44,14 @@ export const makePgPasswordPreparedPersistenceServices = <
40
44
  PCr extends AnyPgTable = AnyPgTable,
41
45
  PNativeId = unknown,
42
46
  >(
43
- database: Database,
44
47
  mapping: PasswordPreparedPersistenceMapping<S, I, C, AC, A, RS, CE, M, T, B, NativeId>,
45
48
  proofMapping?: PasswordPreparedProofMapping<PS, PC, PM, PSub, PI, PCr, PNativeId>,
46
49
  ) =>
47
- makeTargetPasswordPreparedPersistenceServices(
48
- database,
49
- mapping,
50
- configuration(database),
51
- proofMapping,
52
- );
50
+ Effect.flatMap(
51
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
52
+ (configuration) =>
53
+ makeTargetPasswordPreparedPersistenceServices(mapping, configuration, proofMapping),
54
+ ).pipe(Effect.provideServiceEffect(CurrentPasswordSql, nativeDatabase(DatabaseService)));
53
55
 
54
56
  export function coordinatePgPasswordPreparedPersistence<
55
57
  TargetId,
@@ -187,7 +189,7 @@ export function coordinatePgPasswordPreparedPersistence<
187
189
  coordinateTargetPasswordPreparedPersistence<TransactionOf<D>, Out, E, Exclude<R, TargetId>>(
188
190
  database,
189
191
  options.mapping,
190
- configuration(database),
192
+ configuration(transactionService(database)),
191
193
  options.proofMapping,
192
194
  (
193
195
  transaction: TransactionOf<D>,
@@ -6,10 +6,12 @@ import type { EffectPgDatabase as PgliteDatabase } from "drizzle-orm/effect-pgli
6
6
  import type { EffectPgDatabase as PostgresDatabase } from "drizzle-orm/effect-postgres";
7
7
  import type { AnyPgTable } from "drizzle-orm/pg-core";
8
8
  import { Effect, Context } from "effect";
9
- import type { SqlError } from "effect/unstable/sql/SqlError";
9
+ import type { SqlError } from "effect/sql/SqlError";
10
10
 
11
+ import { nativeDatabase } from "./native-database";
11
12
  import type { PasswordPersistenceMapping, PasswordRegistrationMapping } from "./password-model";
12
13
  import type { PasswordRegistrationAuthority } from "./password-registration";
14
+ import { CurrentPasswordSql } from "./password-sql";
13
15
  import type { PasswordSqlQuery } from "./password-sql";
14
16
  import {
15
17
  coordinateTargetPasswordPersistence,
@@ -18,24 +20,30 @@ import {
18
20
  makeTargetPasswordRegistrationServices,
19
21
  sqlClientPasswordStandaloneGuard,
20
22
  } from "./password-target";
23
+ import { Database as DatabaseService } from "./pg-database";
21
24
  import type { ProofPersistenceMapping } from "./proof-model";
22
25
  import type { ProofSqlQuery } from "./proof-sql";
23
26
  import { sqlClientProofStandaloneGuard } from "./proof-target";
27
+ import {
28
+ type TransactionService,
29
+ acquireTransactionService,
30
+ transactionService,
31
+ } from "./standalone-guard";
24
32
  import type { SuppliedService } from "./SuppliedService";
25
33
 
26
34
  type Database = PostgresDatabase<AnyRelations> | PgliteDatabase<AnyRelations>;
27
35
  type TransactionOf<D extends Database> = Parameters<Parameters<D["transaction"]>[0]>[0];
28
36
 
29
- const configuration = (database: Database) => ({
37
+ const configuration = (service: TransactionService | undefined) => ({
30
38
  mode: "interactive" as const,
31
39
  locking: true,
32
- standaloneGuard: sqlClientPasswordStandaloneGuard(database),
40
+ standaloneGuard: sqlClientPasswordStandaloneGuard(service),
33
41
  insertIfAbsent: (query: PasswordSqlQuery) => query.onConflictDoNothing(),
34
42
  generatedSubjectRows: (query: PasswordSqlQuery) => query.returning(),
35
43
  proof: {
36
44
  mode: "interactive" as const,
37
45
  locking: true,
38
- standaloneGuard: sqlClientProofStandaloneGuard(database),
46
+ standaloneGuard: sqlClientProofStandaloneGuard(service),
39
47
  insertIfAbsent: (query: ProofSqlQuery) => query.onConflictDoNothing(),
40
48
  },
41
49
  });
@@ -63,7 +71,6 @@ export const makePgPasswordPersistenceServices = <
63
71
  M extends AnyPgTable,
64
72
  NativeId,
65
73
  >(
66
- database: Database,
67
74
  mapping: PasswordMapping<S, I, C, AC, A, RS, CE, M, NativeId>,
68
75
  proofMapping?: ProofPersistenceMapping<
69
76
  any,
@@ -80,7 +87,10 @@ export const makePgPasswordPersistenceServices = <
80
87
  any
81
88
  >,
82
89
  ) =>
83
- makeTargetPasswordPersistenceServices(database, mapping, configuration(database), proofMapping);
90
+ Effect.flatMap(
91
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
92
+ (configuration) => makeTargetPasswordPersistenceServices(mapping, configuration, proofMapping),
93
+ ).pipe(Effect.provideServiceEffect(CurrentPasswordSql, nativeDatabase(DatabaseService)));
84
94
 
85
95
  export function coordinatePgPasswordPersistence<
86
96
  D extends Database,
@@ -188,7 +198,7 @@ export function coordinatePgPasswordPersistence<
188
198
  coordinateTargetPasswordPersistence<TransactionOf<D>, Out, E, Exclude<R, PasswordPersistence>>(
189
199
  database,
190
200
  options.mapping,
191
- configuration(database),
201
+ configuration(transactionService(database)),
192
202
  options.proofMapping,
193
203
  (
194
204
  transaction: TransactionOf<D>,
@@ -214,10 +224,12 @@ export const makePgPasswordRegistrationServices = <
214
224
  Rq extends AnyPgTable,
215
225
  NativeId,
216
226
  >(
217
- database: Database,
218
227
  mapping: PasswordRegistrationMapping<Registration, S, I, C, AC, Rq, NativeId>,
219
228
  ) =>
220
- makeTargetPasswordRegistrationServices<Registration>(database, mapping, configuration(database));
229
+ Effect.flatMap(
230
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
231
+ (configuration) => makeTargetPasswordRegistrationServices<Registration>(mapping, configuration),
232
+ ).pipe(Effect.provideServiceEffect(CurrentPasswordSql, nativeDatabase(DatabaseService)));
221
233
 
222
234
  export function coordinatePgPasswordRegistration<
223
235
  TargetId,
@@ -319,7 +331,7 @@ export function coordinatePgPasswordRegistration<
319
331
  >(
320
332
  database,
321
333
  options.mapping,
322
- configuration(database),
334
+ configuration(transactionService(database)),
323
335
  (
324
336
  transaction: TransactionOf<D>,
325
337
  services: { readonly registrationAuthority: PasswordRegistrationAuthority<Registration> },
@@ -5,15 +5,23 @@ import type { EffectPgDatabase as PgliteDatabase } from "drizzle-orm/effect-pgli
5
5
  import type { EffectPgDatabase as PostgresDatabase } from "drizzle-orm/effect-postgres";
6
6
  import type { AnyPgTable } from "drizzle-orm/pg-core";
7
7
  import { Effect, Context } from "effect";
8
- import type { SqlError } from "effect/unstable/sql/SqlError";
8
+ import type { SqlError } from "effect/sql/SqlError";
9
9
 
10
+ import { nativeDatabase } from "./native-database";
11
+ import { Database as DatabaseService } from "./pg-database";
10
12
  import type { ProofPersistenceMapping } from "./proof-model";
13
+ import { CurrentProofSql } from "./proof-sql";
11
14
  import type { ProofSqlQuery } from "./proof-sql";
12
15
  import {
13
16
  coordinateTargetProofPersistence,
14
17
  makeTargetProofPersistenceServices,
15
18
  sqlClientProofStandaloneGuard,
16
19
  } from "./proof-target";
20
+ import {
21
+ type TransactionService,
22
+ acquireTransactionService,
23
+ transactionService,
24
+ } from "./standalone-guard";
17
25
  import type { SuppliedService } from "./SuppliedService";
18
26
 
19
27
  type Database = PostgresDatabase<AnyRelations> | PgliteDatabase<AnyRelations>;
@@ -46,10 +54,10 @@ type Mapping<
46
54
  NativeSubjectId
47
55
  >;
48
56
 
49
- const configuration = (database: Database) => ({
57
+ const configuration = (service: TransactionService | undefined) => ({
50
58
  mode: "interactive" as const,
51
59
  locking: true,
52
- standaloneGuard: sqlClientProofStandaloneGuard(database),
60
+ standaloneGuard: sqlClientProofStandaloneGuard(service),
53
61
  insertIfAbsent: (query: ProofSqlQuery) => query.onConflictDoNothing(),
54
62
  });
55
63
 
@@ -67,9 +75,12 @@ export const makePgProofPersistenceServices = <
67
75
  Cr extends AnyPgTable,
68
76
  NativeId,
69
77
  >(
70
- database: Database,
71
78
  mapping: Mapping<Rq, S, G, Cn, Rs, A, F, C, Sub, I, Cr, NativeId>,
72
- ) => makeTargetProofPersistenceServices(database, mapping, configuration(database));
79
+ ) =>
80
+ Effect.flatMap(
81
+ Effect.map(acquireTransactionService(DatabaseService), configuration),
82
+ (configuration) => makeTargetProofPersistenceServices(mapping, configuration),
83
+ ).pipe(Effect.provideServiceEffect(CurrentProofSql, nativeDatabase(DatabaseService)));
73
84
 
74
85
  export function coordinatePgProofPersistence<
75
86
  D extends Database,
@@ -174,7 +185,7 @@ export function coordinatePgProofPersistence<
174
185
  coordinateTargetProofPersistence<TransactionOf<D>, A, E, Exclude<R, ProofPersistence>>(
175
186
  database,
176
187
  options.mapping,
177
- configuration(database),
188
+ configuration(transactionService(database)),
178
189
  (
179
190
  transaction: TransactionOf<D>,
180
191
  services: { readonly proofPersistence: ProofPersistence["Service"] },