@effect-app/infra 4.0.0-beta.99 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. package/CHANGELOG.md +2884 -0
  2. package/_check.sh +1 -1
  3. package/dist/CUPS.d.ts +28 -9
  4. package/dist/CUPS.d.ts.map +1 -1
  5. package/dist/CUPS.js +35 -14
  6. package/dist/ClusterCosmos.d.ts +67 -0
  7. package/dist/ClusterCosmos.d.ts.map +1 -0
  8. package/dist/ClusterCosmos.js +588 -0
  9. package/dist/ClusterServiceBus.d.ts +67 -0
  10. package/dist/ClusterServiceBus.d.ts.map +1 -0
  11. package/dist/ClusterServiceBus.js +84 -0
  12. package/dist/{api/ContextProvider.d.ts → ContextProvider.d.ts} +7 -4
  13. package/dist/ContextProvider.d.ts.map +1 -0
  14. package/dist/ContextProvider.js +40 -0
  15. package/dist/Emailer/Sendgrid.d.ts +110 -146
  16. package/dist/Emailer/Sendgrid.d.ts.map +1 -1
  17. package/dist/Emailer/Sendgrid.js +24 -19
  18. package/dist/Emailer/fake.d.ts +1 -1
  19. package/dist/Emailer/fake.d.ts.map +1 -1
  20. package/dist/Emailer/fake.js +4 -4
  21. package/dist/MainFiberSet.d.ts +11 -7
  22. package/dist/MainFiberSet.d.ts.map +1 -1
  23. package/dist/MainFiberSet.js +22 -6
  24. package/dist/QueueMaker/errors.d.ts +3 -1
  25. package/dist/QueueMaker/errors.d.ts.map +1 -1
  26. package/dist/QueueMaker/errors.js +4 -2
  27. package/dist/{adapters/SQL → SQL}/Model.d.ts +34 -45
  28. package/dist/SQL/Model.d.ts.map +1 -0
  29. package/dist/SQL/Model.js +469 -0
  30. package/dist/SQL.d.ts.map +1 -0
  31. package/dist/{adapters/SQL.js → SQL.js} +1 -1
  32. package/dist/Store/Cosmos/query.d.ts +16 -4
  33. package/dist/Store/Cosmos/query.d.ts.map +1 -1
  34. package/dist/Store/Cosmos/query.js +238 -42
  35. package/dist/Store/Cosmos.d.ts +2 -2
  36. package/dist/Store/Cosmos.d.ts.map +1 -1
  37. package/dist/Store/Cosmos.js +394 -319
  38. package/dist/Store/Disk.d.ts +4 -4
  39. package/dist/Store/Disk.d.ts.map +1 -1
  40. package/dist/Store/Disk.js +91 -39
  41. package/dist/Store/Memory.d.ts +7 -10
  42. package/dist/Store/Memory.d.ts.map +1 -1
  43. package/dist/Store/Memory.js +348 -78
  44. package/dist/Store/SQL/Pg.d.ts +2 -2
  45. package/dist/Store/SQL/Pg.d.ts.map +1 -1
  46. package/dist/Store/SQL/Pg.js +229 -154
  47. package/dist/Store/SQL/query.d.ts +19 -3
  48. package/dist/Store/SQL/query.d.ts.map +1 -1
  49. package/dist/Store/SQL/query.js +306 -12
  50. package/dist/Store/SQL.d.ts +22 -5
  51. package/dist/Store/SQL.d.ts.map +1 -1
  52. package/dist/Store/SQL.js +369 -98
  53. package/dist/Store/codeFilter.d.ts +4 -4
  54. package/dist/Store/codeFilter.d.ts.map +1 -1
  55. package/dist/Store/codeFilter.js +71 -22
  56. package/dist/Store/index.d.ts +6 -4
  57. package/dist/Store/index.d.ts.map +1 -1
  58. package/dist/Store/index.js +9 -6
  59. package/dist/Store/jsonDocument.d.ts +67 -0
  60. package/dist/Store/jsonDocument.d.ts.map +1 -0
  61. package/dist/Store/jsonDocument.js +107 -0
  62. package/dist/Store/utils.d.ts +21 -2
  63. package/dist/Store/utils.d.ts.map +1 -1
  64. package/dist/Store/utils.js +253 -10
  65. package/dist/WorkflowEngineCosmos.d.ts +30 -0
  66. package/dist/WorkflowEngineCosmos.d.ts.map +1 -0
  67. package/dist/WorkflowEngineCosmos.js +542 -0
  68. package/dist/WorkflowEngineSqlite.d.ts +24 -0
  69. package/dist/WorkflowEngineSqlite.d.ts.map +1 -0
  70. package/dist/WorkflowEngineSqlite.js +550 -0
  71. package/dist/arbs.d.ts +6 -3
  72. package/dist/arbs.d.ts.map +1 -1
  73. package/dist/arbs.js +20 -4
  74. package/dist/codec.d.ts.map +1 -0
  75. package/dist/codec.js +5 -0
  76. package/dist/cosmos-client.d.ts +40 -0
  77. package/dist/cosmos-client.d.ts.map +1 -0
  78. package/dist/cosmos-client.js +41 -0
  79. package/dist/errorReporter.d.ts +6 -4
  80. package/dist/errorReporter.d.ts.map +1 -1
  81. package/dist/errorReporter.js +23 -27
  82. package/dist/fileUtil.d.ts +1 -1
  83. package/dist/fileUtil.d.ts.map +1 -1
  84. package/dist/fileUtil.js +2 -2
  85. package/dist/index.d.ts +2 -1
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +3 -2
  88. package/dist/internal/RequestContextMiddleware.d.ts +5 -0
  89. package/dist/internal/RequestContextMiddleware.d.ts.map +1 -0
  90. package/dist/internal/RequestContextMiddleware.js +45 -0
  91. package/dist/internal/auth.d.ts +53 -0
  92. package/dist/internal/auth.d.ts.map +1 -0
  93. package/dist/internal/auth.js +180 -0
  94. package/dist/internal/events.d.ts +11 -0
  95. package/dist/internal/events.d.ts.map +1 -0
  96. package/dist/internal/events.js +49 -0
  97. package/dist/{api/internal → internal}/health.d.ts +1 -1
  98. package/dist/internal/health.d.ts.map +1 -0
  99. package/dist/internal/health.js +5 -0
  100. package/dist/{api/layerUtils.d.ts → layerUtils.d.ts} +10 -2
  101. package/dist/layerUtils.d.ts.map +1 -0
  102. package/dist/layerUtils.js +17 -0
  103. package/dist/logger/jsonLogger.d.ts +1 -1
  104. package/dist/logger/jsonLogger.d.ts.map +1 -1
  105. package/dist/logger/jsonLogger.js +5 -3
  106. package/dist/logger/logFmtLogger.d.ts +1 -1
  107. package/dist/logger/logFmtLogger.d.ts.map +1 -1
  108. package/dist/logger/logFmtLogger.js +3 -3
  109. package/dist/logger/shared.d.ts +2 -2
  110. package/dist/logger/shared.d.ts.map +1 -1
  111. package/dist/logger/shared.js +6 -6
  112. package/dist/logger.d.ts.map +1 -1
  113. package/dist/middlewares.d.ts.map +1 -0
  114. package/dist/{api/middlewares.js → middlewares.js} +1 -1
  115. package/dist/{adapters/mongo-client.d.ts → mongo-client.d.ts} +2 -1
  116. package/dist/mongo-client.d.ts.map +1 -0
  117. package/dist/mongo-client.js +15 -0
  118. package/dist/otel.d.ts +75 -0
  119. package/dist/otel.d.ts.map +1 -0
  120. package/dist/otel.js +84 -0
  121. package/dist/rateLimit.d.ts +11 -3
  122. package/dist/rateLimit.d.ts.map +1 -1
  123. package/dist/rateLimit.js +7 -12
  124. package/dist/{adapters/redis-client.d.ts → redis-client.d.ts} +4 -1
  125. package/dist/redis-client.d.ts.map +1 -0
  126. package/dist/redis-client.js +98 -0
  127. package/dist/{api/reportError.d.ts → reportError.d.ts} +1 -1
  128. package/dist/reportError.d.ts.map +1 -0
  129. package/dist/reportError.js +28 -0
  130. package/dist/{api/routing → routing}/middleware/RouterMiddleware.d.ts +2 -1
  131. package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
  132. package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
  133. package/dist/{api/routing → routing}/middleware/middleware.d.ts +11 -6
  134. package/dist/routing/middleware/middleware.d.ts.map +1 -0
  135. package/dist/routing/middleware/middleware.js +152 -0
  136. package/dist/{api/routing → routing}/middleware.d.ts +0 -1
  137. package/dist/routing/middleware.d.ts.map +1 -0
  138. package/dist/{api/routing → routing}/middleware.js +1 -2
  139. package/dist/routing/schema/jwt.d.ts.map +1 -0
  140. package/dist/routing/schema/jwt.js +12 -0
  141. package/dist/routing/tsort.d.ts.map +1 -0
  142. package/dist/routing/tsort.js +51 -0
  143. package/dist/{api/routing → routing}/utils.d.ts +3 -3
  144. package/dist/routing/utils.d.ts.map +1 -0
  145. package/dist/routing/utils.js +45 -0
  146. package/dist/routing.d.ts +182 -0
  147. package/dist/routing.d.ts.map +1 -0
  148. package/dist/routing.js +256 -0
  149. package/dist/test.d.ts +2 -2
  150. package/dist/test.d.ts.map +1 -1
  151. package/dist/test.js +5 -5
  152. package/dist/util.d.ts.map +1 -0
  153. package/dist/util.js +14 -0
  154. package/docs/cluster-storage.md +26 -0
  155. package/docs/workflow-engine.md +262 -0
  156. package/examples/query.ts +23 -19
  157. package/package.json +36 -364
  158. package/src/CUPS.ts +53 -14
  159. package/src/ClusterCosmos.ts +1170 -0
  160. package/src/ClusterServiceBus.ts +244 -0
  161. package/src/{api/ContextProvider.ts → ContextProvider.ts} +10 -7
  162. package/src/Emailer/Sendgrid.ts +83 -60
  163. package/src/Emailer/fake.ts +4 -4
  164. package/src/MainFiberSet.ts +31 -12
  165. package/src/QueueMaker/errors.ts +3 -1
  166. package/src/{adapters/SQL → SQL}/Model.ts +48 -47
  167. package/src/SQL.ts +1 -0
  168. package/src/Store/Cosmos/query.ts +275 -55
  169. package/src/Store/Cosmos.ts +597 -511
  170. package/src/Store/Disk.ts +145 -71
  171. package/src/Store/Memory.ts +420 -115
  172. package/src/Store/SQL/Pg.ts +352 -268
  173. package/src/Store/SQL/query.ts +366 -20
  174. package/src/Store/SQL.ts +742 -293
  175. package/src/Store/codeFilter.ts +78 -28
  176. package/src/Store/index.ts +18 -13
  177. package/src/Store/jsonDocument.ts +143 -0
  178. package/src/Store/utils.ts +307 -30
  179. package/src/WorkflowEngineCosmos.ts +749 -0
  180. package/src/WorkflowEngineSqlite.ts +813 -0
  181. package/src/arbs.ts +25 -5
  182. package/src/cosmos-client.ts +72 -0
  183. package/src/errorReporter.ts +68 -78
  184. package/src/fileUtil.ts +1 -1
  185. package/src/index.ts +2 -1
  186. package/src/{api/internal → internal}/RequestContextMiddleware.ts +23 -6
  187. package/src/internal/auth.ts +272 -0
  188. package/src/{api/internal → internal}/events.ts +18 -9
  189. package/src/{api/layerUtils.ts → layerUtils.ts} +7 -3
  190. package/src/logger/jsonLogger.ts +5 -3
  191. package/src/logger/logFmtLogger.ts +3 -3
  192. package/src/logger/shared.ts +6 -5
  193. package/src/middlewares.ts +10 -0
  194. package/src/{adapters/mongo-client.ts → mongo-client.ts} +3 -1
  195. package/src/otel.ts +177 -0
  196. package/src/rateLimit.ts +35 -24
  197. package/src/{adapters/redis-client.ts → redis-client.ts} +6 -2
  198. package/src/{api/reportError.ts → reportError.ts} +3 -2
  199. package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +2 -1
  200. package/src/{api/routing → routing}/middleware/middleware.ts +75 -50
  201. package/src/routing/middleware.ts +4 -0
  202. package/src/{api/routing → routing}/schema/jwt.ts +2 -2
  203. package/src/{api/routing → routing}/utils.ts +2 -1
  204. package/src/routing.ts +823 -0
  205. package/src/test.ts +6 -6
  206. package/src/vitest.ts +1 -1
  207. package/test/arbs-magnitude.test.ts +33 -0
  208. package/test/arbs.test.ts +41 -0
  209. package/test/auth.test.ts +101 -0
  210. package/test/cluster-cosmos.test.ts +634 -0
  211. package/test/cluster-servicebus.test.ts +180 -0
  212. package/test/cluster-sqlite.test.ts +207 -0
  213. package/test/contextProvider.test.ts +11 -8
  214. package/test/controller.test.ts +23 -28
  215. package/test/cosmos-container-throughput.test.ts +80 -0
  216. package/test/cosmos-query.test.ts +368 -0
  217. package/test/dist/arbs-magnitude.test.d.ts.map +1 -0
  218. package/test/dist/arbs.test.d.ts.map +1 -0
  219. package/test/dist/auth.test.d.ts.map +1 -0
  220. package/test/dist/cluster-cosmos.test.d.ts.map +1 -0
  221. package/test/dist/cluster-servicebus.test.d.ts.map +1 -0
  222. package/test/dist/cluster-sqlite.test.d.ts.map +1 -0
  223. package/test/dist/contextProvider.test.d.ts.map +1 -1
  224. package/test/dist/controller.test.d.ts.map +1 -1
  225. package/test/dist/cosmos-container-throughput.test.d.ts.map +1 -0
  226. package/test/dist/cosmos-query.test.d.ts.map +1 -0
  227. package/test/dist/fixtures.d.ts +17 -9
  228. package/test/dist/fixtures.d.ts.map +1 -1
  229. package/test/dist/fixtures.js +8 -3
  230. package/test/dist/json-lower.test.d.ts.map +1 -0
  231. package/test/dist/query.test.d.ts.map +1 -1
  232. package/test/dist/rawQuery.test.d.ts.map +1 -1
  233. package/test/dist/repository-ext.test.d.ts.map +1 -0
  234. package/test/dist/repository-legacy-document.test.d.ts.map +1 -0
  235. package/test/dist/requires.test.d.ts.map +1 -1
  236. package/test/dist/router-generator.test.d.ts.map +1 -0
  237. package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
  238. package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
  239. package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
  240. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  241. package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
  242. package/test/dist/workflow-engine-cosmos.test.d.ts.map +1 -0
  243. package/test/dist/workflow-engine-sqlite.test.d.ts.map +1 -0
  244. package/test/fixtures.ts +7 -2
  245. package/test/json-lower.test.ts +129 -0
  246. package/test/layerUtils.test.ts +2 -2
  247. package/test/query.test.ts +1232 -42
  248. package/test/rawQuery.test.ts +432 -7
  249. package/test/repository-ext.test.ts +456 -0
  250. package/test/repository-legacy-document.test.ts +394 -0
  251. package/test/requires.test.ts +7 -3
  252. package/test/router-generator.test.ts +187 -0
  253. package/test/routing-interruptibility.test.ts +66 -0
  254. package/test/rpc-context-map-streaming.test.ts +265 -0
  255. package/test/rpc-e2e-invalidation.test.ts +421 -0
  256. package/test/rpc-multi-middleware.test.ts +17 -11
  257. package/test/rpc-stream-fullstack.test.ts +307 -0
  258. package/test/sql-store.test.ts +1202 -47
  259. package/test/validateSample.test.ts +70 -42
  260. package/test/workflow-engine-cosmos.test.ts +345 -0
  261. package/test/workflow-engine-sqlite.test.ts +297 -0
  262. package/tsconfig.examples.json +1 -1
  263. package/tsconfig.json +9 -1
  264. package/tsconfig.src.json +35 -35
  265. package/tsconfig.test.json +2 -2
  266. package/dist/Emailer/service.d.ts +0 -55
  267. package/dist/Emailer/service.d.ts.map +0 -1
  268. package/dist/Emailer/service.js +0 -6
  269. package/dist/Emailer.d.ts +0 -2
  270. package/dist/Emailer.d.ts.map +0 -1
  271. package/dist/Emailer.js +0 -2
  272. package/dist/Model/Repository/ext.d.ts +0 -41
  273. package/dist/Model/Repository/ext.d.ts.map +0 -1
  274. package/dist/Model/Repository/ext.js +0 -65
  275. package/dist/Model/Repository/internal/internal.d.ts +0 -59
  276. package/dist/Model/Repository/internal/internal.d.ts.map +0 -1
  277. package/dist/Model/Repository/internal/internal.js +0 -320
  278. package/dist/Model/Repository/legacy.d.ts +0 -19
  279. package/dist/Model/Repository/legacy.d.ts.map +0 -1
  280. package/dist/Model/Repository/legacy.js +0 -2
  281. package/dist/Model/Repository/makeRepo.d.ts +0 -49
  282. package/dist/Model/Repository/makeRepo.d.ts.map +0 -1
  283. package/dist/Model/Repository/makeRepo.js +0 -24
  284. package/dist/Model/Repository/service.d.ts +0 -89
  285. package/dist/Model/Repository/service.d.ts.map +0 -1
  286. package/dist/Model/Repository/service.js +0 -2
  287. package/dist/Model/Repository/validation.d.ts +0 -43
  288. package/dist/Model/Repository/validation.d.ts.map +0 -1
  289. package/dist/Model/Repository/validation.js +0 -32
  290. package/dist/Model/Repository.d.ts +0 -6
  291. package/dist/Model/Repository.d.ts.map +0 -1
  292. package/dist/Model/Repository.js +0 -6
  293. package/dist/Model/dsl.d.ts +0 -32
  294. package/dist/Model/dsl.d.ts.map +0 -1
  295. package/dist/Model/dsl.js +0 -44
  296. package/dist/Model/filter/filterApi.d.ts +0 -30
  297. package/dist/Model/filter/filterApi.d.ts.map +0 -1
  298. package/dist/Model/filter/filterApi.js +0 -2
  299. package/dist/Model/filter/types/errors.d.ts +0 -29
  300. package/dist/Model/filter/types/errors.d.ts.map +0 -1
  301. package/dist/Model/filter/types/errors.js +0 -2
  302. package/dist/Model/filter/types/fields.d.ts +0 -15
  303. package/dist/Model/filter/types/fields.d.ts.map +0 -1
  304. package/dist/Model/filter/types/fields.js +0 -2
  305. package/dist/Model/filter/types/path/common.d.ts +0 -316
  306. package/dist/Model/filter/types/path/common.d.ts.map +0 -1
  307. package/dist/Model/filter/types/path/common.js +0 -2
  308. package/dist/Model/filter/types/path/eager.d.ts +0 -95
  309. package/dist/Model/filter/types/path/eager.d.ts.map +0 -1
  310. package/dist/Model/filter/types/path/eager.js +0 -31
  311. package/dist/Model/filter/types/path/index.d.ts +0 -4
  312. package/dist/Model/filter/types/path/index.d.ts.map +0 -1
  313. package/dist/Model/filter/types/path/index.js +0 -3
  314. package/dist/Model/filter/types/utils.d.ts +0 -79
  315. package/dist/Model/filter/types/utils.d.ts.map +0 -1
  316. package/dist/Model/filter/types/utils.js +0 -2
  317. package/dist/Model/filter/types/validator.d.ts +0 -30
  318. package/dist/Model/filter/types/validator.d.ts.map +0 -1
  319. package/dist/Model/filter/types/validator.js +0 -2
  320. package/dist/Model/filter/types.d.ts +0 -5
  321. package/dist/Model/filter/types.d.ts.map +0 -1
  322. package/dist/Model/filter/types.js +0 -7
  323. package/dist/Model/query/dsl.d.ts +0 -248
  324. package/dist/Model/query/dsl.d.ts.map +0 -1
  325. package/dist/Model/query/dsl.js +0 -104
  326. package/dist/Model/query/new-kid-interpreter.d.ts +0 -28
  327. package/dist/Model/query/new-kid-interpreter.d.ts.map +0 -1
  328. package/dist/Model/query/new-kid-interpreter.js +0 -165
  329. package/dist/Model/query.d.ts +0 -15
  330. package/dist/Model/query.d.ts.map +0 -1
  331. package/dist/Model/query.js +0 -3
  332. package/dist/Model.d.ts +0 -4
  333. package/dist/Model.d.ts.map +0 -1
  334. package/dist/Model.js +0 -4
  335. package/dist/Operations.d.ts +0 -55
  336. package/dist/Operations.d.ts.map +0 -1
  337. package/dist/Operations.js +0 -102
  338. package/dist/OperationsRepo.d.ts +0 -41
  339. package/dist/OperationsRepo.d.ts.map +0 -1
  340. package/dist/OperationsRepo.js +0 -14
  341. package/dist/QueueMaker/SQLQueue.d.ts +0 -14
  342. package/dist/QueueMaker/SQLQueue.d.ts.map +0 -1
  343. package/dist/QueueMaker/SQLQueue.js +0 -132
  344. package/dist/QueueMaker/memQueue.d.ts +0 -11
  345. package/dist/QueueMaker/memQueue.d.ts.map +0 -1
  346. package/dist/QueueMaker/memQueue.js +0 -76
  347. package/dist/QueueMaker/sbqueue.d.ts +0 -12
  348. package/dist/QueueMaker/sbqueue.d.ts.map +0 -1
  349. package/dist/QueueMaker/sbqueue.js +0 -91
  350. package/dist/QueueMaker/service.d.ts +0 -11
  351. package/dist/QueueMaker/service.d.ts.map +0 -1
  352. package/dist/QueueMaker/service.js +0 -4
  353. package/dist/RequestContext.d.ts +0 -68
  354. package/dist/RequestContext.d.ts.map +0 -1
  355. package/dist/RequestContext.js +0 -49
  356. package/dist/RequestFiberSet.d.ts +0 -36
  357. package/dist/RequestFiberSet.d.ts.map +0 -1
  358. package/dist/RequestFiberSet.js +0 -78
  359. package/dist/Store/ContextMapContainer.d.ts +0 -25
  360. package/dist/Store/ContextMapContainer.d.ts.map +0 -1
  361. package/dist/Store/ContextMapContainer.js +0 -77
  362. package/dist/Store/service.d.ts +0 -111
  363. package/dist/Store/service.d.ts.map +0 -1
  364. package/dist/Store/service.js +0 -79
  365. package/dist/Store.d.ts +0 -2
  366. package/dist/Store.d.ts.map +0 -1
  367. package/dist/Store.js +0 -2
  368. package/dist/adapters/SQL/Model.d.ts.map +0 -1
  369. package/dist/adapters/SQL/Model.js +0 -478
  370. package/dist/adapters/SQL.d.ts.map +0 -1
  371. package/dist/adapters/ServiceBus.d.ts +0 -58
  372. package/dist/adapters/ServiceBus.d.ts.map +0 -1
  373. package/dist/adapters/ServiceBus.js +0 -99
  374. package/dist/adapters/cosmos-client.d.ts +0 -14
  375. package/dist/adapters/cosmos-client.d.ts.map +0 -1
  376. package/dist/adapters/cosmos-client.js +0 -9
  377. package/dist/adapters/index.d.ts +0 -2
  378. package/dist/adapters/index.d.ts.map +0 -1
  379. package/dist/adapters/index.js +0 -2
  380. package/dist/adapters/logger.d.ts +0 -9
  381. package/dist/adapters/logger.d.ts.map +0 -1
  382. package/dist/adapters/logger.js +0 -3
  383. package/dist/adapters/memQueue.d.ts +0 -13
  384. package/dist/adapters/memQueue.d.ts.map +0 -1
  385. package/dist/adapters/memQueue.js +0 -20
  386. package/dist/adapters/mongo-client.d.ts.map +0 -1
  387. package/dist/adapters/mongo-client.js +0 -13
  388. package/dist/adapters/redis-client.d.ts.map +0 -1
  389. package/dist/adapters/redis-client.js +0 -94
  390. package/dist/api/ContextProvider.d.ts.map +0 -1
  391. package/dist/api/ContextProvider.js +0 -38
  392. package/dist/api/codec.d.ts.map +0 -1
  393. package/dist/api/codec.js +0 -5
  394. package/dist/api/internal/RequestContextMiddleware.d.ts +0 -5
  395. package/dist/api/internal/RequestContextMiddleware.d.ts.map +0 -1
  396. package/dist/api/internal/RequestContextMiddleware.js +0 -35
  397. package/dist/api/internal/auth.d.ts +0 -15
  398. package/dist/api/internal/auth.d.ts.map +0 -1
  399. package/dist/api/internal/auth.js +0 -47
  400. package/dist/api/internal/events.d.ts +0 -9
  401. package/dist/api/internal/events.d.ts.map +0 -1
  402. package/dist/api/internal/events.js +0 -42
  403. package/dist/api/internal/health.d.ts.map +0 -1
  404. package/dist/api/internal/health.js +0 -5
  405. package/dist/api/layerUtils.d.ts.map +0 -1
  406. package/dist/api/layerUtils.js +0 -16
  407. package/dist/api/middlewares.d.ts.map +0 -1
  408. package/dist/api/reportError.d.ts.map +0 -1
  409. package/dist/api/reportError.js +0 -27
  410. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +0 -1
  411. package/dist/api/routing/middleware/middleware.d.ts.map +0 -1
  412. package/dist/api/routing/middleware/middleware.js +0 -130
  413. package/dist/api/routing/middleware.d.ts.map +0 -1
  414. package/dist/api/routing/schema/jwt.d.ts.map +0 -1
  415. package/dist/api/routing/schema/jwt.js +0 -12
  416. package/dist/api/routing/tsort.d.ts.map +0 -1
  417. package/dist/api/routing/tsort.js +0 -51
  418. package/dist/api/routing/utils.d.ts.map +0 -1
  419. package/dist/api/routing/utils.js +0 -44
  420. package/dist/api/routing.d.ts +0 -134
  421. package/dist/api/routing.d.ts.map +0 -1
  422. package/dist/api/routing.js +0 -167
  423. package/dist/api/setupRequest.d.ts +0 -15
  424. package/dist/api/setupRequest.d.ts.map +0 -1
  425. package/dist/api/setupRequest.js +0 -49
  426. package/dist/api/util.d.ts.map +0 -1
  427. package/dist/api/util.js +0 -14
  428. package/eslint.config.mjs +0 -24
  429. package/src/Emailer/service.ts +0 -52
  430. package/src/Emailer.ts +0 -1
  431. package/src/Model/Repository/ext.ts +0 -283
  432. package/src/Model/Repository/internal/internal.ts +0 -580
  433. package/src/Model/Repository/legacy.ts +0 -27
  434. package/src/Model/Repository/makeRepo.ts +0 -139
  435. package/src/Model/Repository/service.ts +0 -627
  436. package/src/Model/Repository/validation.ts +0 -31
  437. package/src/Model/Repository.ts +0 -5
  438. package/src/Model/dsl.ts +0 -128
  439. package/src/Model/filter/filterApi.ts +0 -60
  440. package/src/Model/filter/types/errors.ts +0 -47
  441. package/src/Model/filter/types/fields.ts +0 -50
  442. package/src/Model/filter/types/path/common.ts +0 -404
  443. package/src/Model/filter/types/path/eager.ts +0 -298
  444. package/src/Model/filter/types/path/index.ts +0 -4
  445. package/src/Model/filter/types/utils.ts +0 -128
  446. package/src/Model/filter/types/validator.ts +0 -46
  447. package/src/Model/filter/types.ts +0 -6
  448. package/src/Model/query/dsl.ts +0 -2110
  449. package/src/Model/query/new-kid-interpreter.ts +0 -210
  450. package/src/Model/query.ts +0 -13
  451. package/src/Model.ts +0 -3
  452. package/src/Operations.ts +0 -235
  453. package/src/OperationsRepo.ts +0 -16
  454. package/src/QueueMaker/SQLQueue.ts +0 -190
  455. package/src/QueueMaker/memQueue.ts +0 -130
  456. package/src/QueueMaker/sbqueue.ts +0 -137
  457. package/src/QueueMaker/service.ts +0 -17
  458. package/src/RequestContext.ts +0 -63
  459. package/src/RequestFiberSet.ts +0 -105
  460. package/src/Store/ContextMapContainer.ts +0 -116
  461. package/src/Store/index.test.ts.bak +0 -112
  462. package/src/Store/service.ts +0 -193
  463. package/src/Store.ts +0 -1
  464. package/src/adapters/SQL.ts +0 -1
  465. package/src/adapters/ServiceBus.ts +0 -209
  466. package/src/adapters/cosmos-client.ts +0 -16
  467. package/src/adapters/index.ts +0 -0
  468. package/src/adapters/logger.ts +0 -3
  469. package/src/adapters/memQueue.ts +0 -21
  470. package/src/api/internal/auth.ts +0 -68
  471. package/src/api/middlewares.ts +0 -10
  472. package/src/api/routing/middleware.ts +0 -6
  473. package/src/api/routing.ts +0 -598
  474. package/src/api/setupRequest.ts +0 -104
  475. package/test/dist/date-query.test.d.ts.map +0 -1
  476. package/tsconfig.json.bak +0 -12
  477. /package/dist/{adapters/SQL.d.ts → SQL.d.ts} +0 -0
  478. /package/dist/{api/codec.d.ts → codec.d.ts} +0 -0
  479. /package/dist/{api/middlewares.d.ts → middlewares.d.ts} +0 -0
  480. /package/dist/{api/routing → routing}/schema/jwt.d.ts +0 -0
  481. /package/dist/{api/routing → routing}/tsort.d.ts +0 -0
  482. /package/dist/{api/util.d.ts → util.d.ts} +0 -0
  483. /package/src/{api/codec.ts → codec.ts} +0 -0
  484. /package/src/{api/internal → internal}/health.ts +0 -0
  485. /package/src/{api/routing → routing}/tsort.ts +0 -0
  486. /package/src/{api/util.ts → util.ts} +0 -0
@@ -1,23 +1,52 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
 
3
- import { Effect, type NonEmptyReadonlyArray, Option, Struct } from "effect-app"
3
+ import type { NonEmptyReadonlyArray } from "effect-app/Array"
4
4
  import { toNonEmptyArray } from "effect-app/Array"
5
- import { SqlClient } from "effect/unstable/sql"
6
- import { OptimisticConcurrencyException } from "../../errors.js"
7
- import { InfraLogger } from "../../logger.js"
8
- import type { FieldValues } from "../../Model/filter/types.js"
9
- import { storeId } from "../Memory.js"
10
- import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, StoreMaker } from "../service.js"
11
- import { makeETag } from "../utils.js"
12
- import { buildWhereSQLQuery, logQuery, pgDialect } from "./query.js"
5
+ import * as Effect from "effect-app/Effect"
6
+ import type { FieldValues } from "effect-app/Model/filter/types"
7
+ import type { ComputedProjectionIrExpression } from "effect-app/Model/query"
8
+ import * as Option from "effect-app/Option"
9
+ import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, storeId, StoreMaker } from "effect-app/Store"
10
+ import { SqlClient } from "effect/sql"
11
+ import * as Struct from "effect/Struct"
12
+ import { DatabaseError, OptimisticConcurrencyException } from "../../errors.ts"
13
+ import { InfraLogger } from "../../logger.ts"
14
+ import { annotateDb } from "../../otel.ts"
15
+ import { decodeStoredMany, decodeStoredOption, makeJsonDocumentCodec, makeStoredDecode } from "../jsonDocument.ts"
16
+ import { makeETag, makeJsonLower, toJsonQueryValue } from "../utils.ts"
17
+ import { buildWhereSQLQuery, logQuery, pgDialect } from "./query.ts"
13
18
 
19
+ const sqlErrorMessage = (e: unknown) => (e as any)?.message ? String((e as any).message) : String(e)
20
+ const sqlIsTransient = (e: unknown) =>
21
+ /timeout|ETIMEDOUT|ECONNRESET|ECONNREFUSED|connection|deadlock|too many connections/i.test(sqlErrorMessage(e))
22
+ // Map a SqlError into a typed, serializable DatabaseError (instead of `.orDie`,
23
+ // which would turn it into an opaque, non-serializable defect).
24
+ const toDatabaseError = (e: unknown) =>
25
+ new DatabaseError({ message: `SQL request failed: ${sqlErrorMessage(e)}`, transient: sqlIsTransient(e), cause: e })
26
+ // withTransaction may re-raise setInternal's typed errors or add SqlError on begin/commit.
27
+ // Preserve DatabaseError / OCC by `_tag` (not instanceof — dual package instances break it);
28
+ // map residual SQL failures to DatabaseError.
29
+ const preserveStoreError = (e: unknown): DatabaseError | OptimisticConcurrencyException => {
30
+ if (e !== null && typeof e === "object" && "_tag" in e) {
31
+ if (e._tag === "DatabaseError") return e as DatabaseError
32
+ if (e._tag === "OptimisticConcurrencyException") return e as OptimisticConcurrencyException
33
+ }
34
+ return toDatabaseError(e)
35
+ }
36
+
37
+ /**
38
+ * Row -> raw stored JSON document. Decoding it is a separate step
39
+ * (`makeStoredDecode`), so a document `jitM` does not repair fails as a typed
40
+ * `S.SchemaError` rather than throwing out of here.
41
+ */
14
42
  const parseRow = <Encoded extends FieldValues>(
15
43
  row: { id: string; _etag: string | null; data: unknown },
16
44
  idKey: PropertyKey,
17
45
  defaultValues: Partial<Encoded>
18
46
  ): PersistenceModelType<Encoded> => {
19
47
  const data = (typeof row.data === "string" ? JSON.parse(row.data) : row.data) as object
20
- return { ...defaultValues, ...data, [idKey]: row.id, _etag: row._etag ?? undefined } as PersistenceModelType<Encoded>
48
+ const jsonDefaults = toJsonQueryValue(defaultValues) as Partial<Encoded>
49
+ return { ...jsonDefaults, ...data, [idKey]: row.id, _etag: row._etag ?? undefined } as PersistenceModelType<Encoded>
21
50
  }
22
51
 
23
52
  const parseSelectRow = (
@@ -37,290 +66,345 @@ const parseSelectRow = (
37
66
  return result
38
67
  }
39
68
 
40
- function makePgStore({ prefix }: StorageConfig) {
41
- return Effect.gen(function*() {
42
- const sql = yield* SqlClient.SqlClient
43
- return {
44
- make: <IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>(
45
- name: string,
46
- idKey: IdKey,
47
- seed?: Effect.Effect<Iterable<Encoded>, E, R>,
48
- config?: StoreConfig<Encoded>
49
- ) =>
50
- Effect.gen(function*() {
51
- type PM = PersistenceModelType<Encoded>
52
- const tableName = `${prefix}${name}`
53
- const defaultValues = config?.defaultValues ?? {}
69
+ const makePgStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
70
+ const sql = yield* SqlClient.SqlClient
71
+ return {
72
+ make: Effect.fnUntraced(function*<IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>(
73
+ name: string,
74
+ idKey: IdKey,
75
+ seed?: Effect.Effect<Iterable<Encoded>, E, R>,
76
+ config?: StoreConfig<Encoded>
77
+ ) {
78
+ type PM = PersistenceModelType<Encoded>
79
+ const tableName = `${prefix}${name}`
80
+ const json = makeJsonLower(config)
81
+ const defaultValues = json.toJson(config?.defaultValues ?? {}) as Partial<Encoded>
82
+ const codec = makeJsonDocumentCodec<Encoded>(config?.schema)
83
+ // read path: stored JSON -> defaultValues -> jitM -> JSON→Encoded decode
84
+ const decodeStored = makeStoredDecode<Encoded>(config?.schema, config?.jitM)
85
+ const decodeRow = (row: { id: string; _etag: string | null; data: unknown }) =>
86
+ decodeStored(parseRow<Encoded>(row, idKey, defaultValues))
54
87
 
55
- const resolveNamespace = !config?.allowNamespace
56
- ? Effect.succeed("primary")
57
- : storeId.asEffect().pipe(Effect.map((namespace) => {
58
- if (namespace !== "primary" && !config.allowNamespace!(namespace)) {
59
- throw new Error(`Namespace ${namespace} not allowed!`)
60
- }
61
- return namespace
62
- }))
88
+ const resolveNamespace = !config?.allowNamespace
89
+ ? Effect.succeed("primary")
90
+ : storeId.pipe(Effect.map((namespace) => {
91
+ if (namespace !== "primary" && !config.allowNamespace!(namespace)) {
92
+ throw new Error(`Namespace ${namespace} not allowed!`)
93
+ }
94
+ return namespace
95
+ }))
63
96
 
64
- yield* sql
65
- .unsafe(
66
- `CREATE TABLE IF NOT EXISTS "${tableName}" (id TEXT NOT NULL, _namespace TEXT NOT NULL DEFAULT 'primary', _etag TEXT, data JSONB NOT NULL, PRIMARY KEY (id, _namespace))`
97
+ const ensureTable = sql
98
+ .unsafe(
99
+ `CREATE TABLE IF NOT EXISTS "${tableName}" (id TEXT NOT NULL, _namespace TEXT NOT NULL DEFAULT 'primary', _etag TEXT, data JSONB NOT NULL, PRIMARY KEY (id, _namespace))`
100
+ )
101
+ .pipe(
102
+ Effect.andThen(
103
+ sql.unsafe(
104
+ `CREATE TABLE IF NOT EXISTS "_migrations" (id TEXT NOT NULL, version TEXT NOT NULL, PRIMARY KEY (id, version))`
67
105
  )
68
- .pipe(Effect.orDie)
106
+ ),
107
+ Effect.orDie,
108
+ Effect.asVoid
109
+ )
69
110
 
70
- const toRow = (e: PM) => {
71
- const newE = makeETag(e)
72
- const id = newE[idKey] as string
73
- const { _etag, [idKey]: _id, ...rest } = newE as any
74
- const data = JSON.stringify(rest)
75
- return { id, _etag: newE._etag!, data, item: newE }
76
- }
77
-
78
- const exec = (query: string, params?: readonly unknown[]) =>
79
- sql.unsafe(query, params as any).pipe(Effect.orDie)
111
+ const toRow = (e: PM) => {
112
+ const newE = makeETag(codec.encode(e))
113
+ const id = newE[idKey] as string
114
+ const { _etag, [idKey]: _id, ...rest } = newE as any
115
+ const data = JSON.stringify(rest)
116
+ return { id, _etag: newE._etag!, data, item: codec.decode(newE) }
117
+ }
80
118
 
81
- const seedMarkerId = `__seed_marker__`
119
+ const exec = (query: string, params?: readonly unknown[]) =>
120
+ sql.unsafe(query, params as any).pipe(Effect.mapError(toDatabaseError))
82
121
 
83
- const setInternal = (e: PM, ns: string) =>
84
- Effect.gen(function*() {
85
- const row = toRow(e)
86
- if (e._etag) {
87
- yield* exec(
88
- `UPDATE "${tableName}" SET _etag = $1, data = $2 WHERE id = $3 AND _etag = $4 AND _namespace = $5`,
89
- [row._etag, row.data, row.id, e._etag, ns]
90
- )
91
- const existing = yield* exec(
92
- `SELECT _etag FROM "${tableName}" WHERE id = $1 AND _namespace = $2`,
93
- [row.id, ns]
94
- )
95
- const current = (existing as any[])[0]
96
- if (!current || current._etag !== row._etag) {
97
- if (current) {
98
- return yield* new OptimisticConcurrencyException({
99
- type: name,
100
- id: row.id,
101
- current: current._etag,
102
- found: e._etag,
103
- code: 412
104
- })
105
- }
106
- return yield* new OptimisticConcurrencyException({
107
- type: name,
108
- id: row.id,
109
- current: "",
110
- found: e._etag,
111
- code: 404
112
- })
113
- }
114
- } else {
115
- yield* exec(
116
- `INSERT INTO "${tableName}" (id, _namespace, _etag, data) VALUES ($1, $2, $3, $4)`,
117
- [row.id, ns, row._etag, row.data]
118
- )
119
- }
120
- return row.item
122
+ const setInternal = Effect.fnUntraced(function*(e: PM, ns: string) {
123
+ const row = toRow(e)
124
+ if (e._etag) {
125
+ yield* exec(
126
+ `UPDATE "${tableName}" SET _etag = $1, data = $2 WHERE id = $3 AND _etag = $4 AND _namespace = $5`,
127
+ [row._etag, row.data, row.id, e._etag, ns]
128
+ )
129
+ const existing = yield* exec(
130
+ `SELECT _etag FROM "${tableName}" WHERE id = $1 AND _namespace = $2`,
131
+ [row.id, ns]
132
+ )
133
+ const current = (existing as any[])[0]
134
+ if (!current || current._etag !== row._etag) {
135
+ if (current) {
136
+ return yield* new OptimisticConcurrencyException({
137
+ type: name,
138
+ id: row.id,
139
+ current: current._etag,
140
+ found: e._etag,
141
+ code: 412
142
+ })
143
+ }
144
+ return yield* new OptimisticConcurrencyException({
145
+ type: name,
146
+ id: row.id,
147
+ current: "",
148
+ found: e._etag,
149
+ code: 404
121
150
  })
151
+ }
152
+ } else {
153
+ yield* exec(
154
+ `INSERT INTO "${tableName}" (id, _namespace, _etag, data) VALUES ($1, $2, $3, $4)`,
155
+ [row.id, ns, row._etag, row.data]
156
+ )
157
+ }
158
+ return row.item
159
+ })
122
160
 
123
- const bulkSetInternal = (items: NonEmptyReadonlyArray<PM>, ns: string) =>
124
- sql
125
- .withTransaction(Effect.forEach(items, (e) => setInternal(e, ns)))
126
- .pipe(
127
- Effect.orDie,
128
- Effect.map((_) => _ as unknown as NonEmptyReadonlyArray<PM>)
129
- )
161
+ const bulkSetInternal = (items: NonEmptyReadonlyArray<PM>, ns: string) =>
162
+ sql
163
+ .withTransaction(Effect.forEach(items, (e) => setInternal(e, ns)))
164
+ .pipe(
165
+ Effect.mapError(preserveStoreError),
166
+ Effect.map((_) => _ as unknown as NonEmptyReadonlyArray<PM>)
167
+ )
130
168
 
131
- const ctx = yield* Effect.context<R>()
132
- const seedCache = new Map<string, Effect.Effect<void>>()
133
- const makeSeedEffect = (ns: string) =>
134
- exec(
135
- `SELECT id FROM "${tableName}" WHERE id = $1 AND _namespace = $2`,
136
- [seedMarkerId, `__seed__::${ns}`]
137
- )
169
+ const ctx = yield* Effect.context<R>()
170
+ const seedCache = new Map<string, Effect.Effect<void, DatabaseError>>()
171
+ const makeSeedEffect = Effect.fnUntraced(function*(ns: string) {
172
+ yield* ensureTable
173
+ if (!seed) return
174
+ const existing = yield* exec(
175
+ `SELECT id FROM "_migrations" WHERE id = $1 AND version = $2`,
176
+ [`${tableName}::${ns}`, tableName]
177
+ )
178
+ if ((existing as any[]).length > 0) return
179
+ yield* InfraLogger.logInfo(`Seeding data for ${name} (namespace: ${ns})`)
180
+ const items = yield* seed.pipe(Effect.provide(ctx), Effect.orDie)
181
+ const ne = toNonEmptyArray([...items])
182
+ // Seed inserts are not concurrent; OCC here is a programming defect.
183
+ if (Option.isSome(ne)) {
184
+ yield* bulkSetInternal(ne.value, ns).pipe(
185
+ Effect.catchTag("OptimisticConcurrencyException", Effect.die)
186
+ )
187
+ }
188
+ yield* exec(
189
+ `INSERT INTO "_migrations" (id, version) VALUES ($1, $2)`,
190
+ [`${tableName}::${ns}`, tableName]
191
+ )
192
+ })
193
+ const seedNamespace = (ns: string) => {
194
+ let cached = seedCache.get(ns)
195
+ if (!cached) {
196
+ cached = Effect.cached(Effect.uninterruptible(makeSeedEffect(ns))).pipe(Effect.runSync)
197
+ seedCache.set(ns, cached)
198
+ }
199
+ return cached
200
+ }
201
+ const selectAllSql = `SELECT id, _etag, data FROM "${tableName}" WHERE _namespace = $1`
202
+ const allStored = resolveNamespace.pipe(
203
+ Effect.flatMap((ns) =>
204
+ exec(selectAllSql, [ns]).pipe(
205
+ Effect.map((rows) => (rows as any[]).map((row) => parseRow<Encoded>(row, idKey, defaultValues)))
206
+ )
207
+ )
208
+ )
209
+
210
+ const s: Store<IdKey, Encoded> = {
211
+ seedNamespace: (ns) => seedNamespace(ns),
212
+
213
+ all: resolveNamespace.pipe(
214
+ Effect.flatMap((ns) => {
215
+ return exec(selectAllSql, [ns])
138
216
  .pipe(
139
- Effect.flatMap((existing) => {
140
- if ((existing as any[]).length > 0) return Effect.void
141
- return InfraLogger.logInfo(`Seeding data for ${name} (namespace: ${ns})`).pipe(
142
- Effect.andThen(seed!),
143
- Effect.flatMap((items) =>
144
- Effect.flatMapOption(
145
- Effect.succeed(toNonEmptyArray([...items])),
146
- (a) => bulkSetInternal(a, ns)
147
- )
148
- ),
149
- Effect.andThen(
150
- exec(
151
- `INSERT INTO "${tableName}" (id, _namespace, _etag, data) VALUES ($1, $2, $3, $4)`,
152
- [seedMarkerId, `__seed__::${ns}`, null, JSON.stringify({ _marker: true })]
153
- )
154
- ),
155
- Effect.provide(ctx),
156
- Effect.orDie
157
- )
217
+ Effect.flatMap((rows) => Effect.fromResult(decodeStoredMany(rows as any[], decodeRow))),
218
+ annotateDb({
219
+ operation: "all",
220
+ system: "postgresql",
221
+ collection: tableName,
222
+ namespace: ns,
223
+ entity: name,
224
+ query: selectAllSql
158
225
  })
159
226
  )
160
- const seedNamespace = Effect.fn("seedNamespace")(function*(ns: string) {
161
- if (!seed) return
162
- let cached = seedCache.get(ns)
163
- if (!cached) {
164
- cached = yield* Effect.cached(makeSeedEffect(ns))
165
- seedCache.set(ns, cached)
166
- }
167
- yield* cached
168
227
  })
169
- const resolveAndSeed = resolveNamespace.pipe(
170
- Effect.tap((ns) => seedNamespace(ns))
171
- )
228
+ ),
172
229
 
173
- const s: Store<IdKey, Encoded> = {
174
- all: resolveAndSeed.pipe(Effect.flatMap((ns) =>
175
- exec(`SELECT id, _etag, data FROM "${tableName}" WHERE _namespace = $1`, [ns])
230
+ find: (id) =>
231
+ resolveNamespace.pipe(Effect
232
+ .flatMap((ns) => {
233
+ const sqlText = `SELECT id, _etag, data FROM "${tableName}" WHERE id = $1 AND _namespace = $2`
234
+ return exec(sqlText, [id, ns])
176
235
  .pipe(
177
- Effect.map((rows) => (rows as any[]).map((r) => parseRow<Encoded>(r, idKey, defaultValues))),
178
- Effect.withSpan("PgSQL.all [effect-app/infra/Store]", {
179
- attributes: {
180
- "repository.table_name": tableName,
181
- "repository.model_name": name,
182
- "repository.namespace": ns
183
- }
184
- }, { captureStackTrace: false })
236
+ Effect.flatMap((rows) =>
237
+ Effect.fromResult(decodeStoredOption(Option.fromNullishOr((rows as any[])[0]), decodeRow))
238
+ ),
239
+ annotateDb({
240
+ operation: "find",
241
+ system: "postgresql",
242
+ collection: tableName,
243
+ namespace: ns,
244
+ entity: name,
245
+ query: sqlText,
246
+ extra: { "app.entity.id": id }
247
+ })
185
248
  )
186
- )),
187
-
188
- find: (id) =>
189
- resolveAndSeed.pipe(Effect
190
- .flatMap((ns) =>
191
- exec(`SELECT id, _etag, data FROM "${tableName}" WHERE id = $1 AND _namespace = $2`, [id, ns])
192
- .pipe(
193
- Effect.map((rows) => {
194
- const row = (rows as any[])[0]
195
- return row
196
- ? Option.some(parseRow<Encoded>(row, idKey, defaultValues))
197
- : Option.none()
198
- }),
199
- Effect.withSpan("PgSQL.find [effect-app/infra/Store]", {
200
- attributes: { "repository.table_name": tableName, "repository.model_name": name, id }
201
- }, { captureStackTrace: false })
202
- )
203
- )),
249
+ })),
204
250
 
205
- filter: <U extends keyof Encoded = never>(f: FilterArgs<Encoded, U>) => {
206
- const filter = f
207
- .filter
208
- type M = U extends undefined ? Encoded : Pick<Encoded, U>
209
- return resolveAndSeed.pipe(Effect.flatMap((ns) =>
210
- Effect
211
- .sync(() => {
212
- const q = buildWhereSQLQuery(
213
- pgDialect,
214
- idKey,
215
- filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [],
216
- tableName,
217
- defaultValues,
218
- f.select as
219
- | NonEmptyReadonlyArray<string | { key: string; subKeys: readonly string[] }>
220
- | undefined,
221
- f.order as NonEmptyReadonlyArray<{ key: string; direction: "ASC" | "DESC" }> | undefined,
222
- f.skip,
223
- f.limit
224
- )
225
- const nsPlaceholder = pgDialect.placeholder(q.params.length + 1)
226
- const hasWhere = q.sql.includes("WHERE")
227
- const nsSql = hasWhere
228
- ? q.sql.replace("WHERE", `WHERE _namespace = ${nsPlaceholder} AND`)
229
- : q.sql.replace(
230
- `FROM "${tableName}"`,
231
- `FROM "${tableName}" WHERE _namespace = ${nsPlaceholder}`
232
- )
233
- return { sql: nsSql, params: [...q.params, ns] }
234
- })
235
- .pipe(
236
- Effect.tap((q) => logQuery(q)),
237
- Effect.flatMap((q) =>
238
- exec(q.sql, q.params).pipe(
239
- Effect.map((rows) => {
240
- if (f.select) {
241
- return (rows as any[]).map((r) => {
242
- const selected = parseSelectRow(r, idKey, {})
243
- return {
244
- ...Struct.pick(
245
- defaultValues as any,
246
- f.select!.filter((_) => typeof _ === "string") as never[]
247
- ),
248
- ...selected
249
- } as M
250
- })
251
- }
252
- return (rows as any[]).map((r) => parseRow<Encoded>(r, idKey, defaultValues) as any as M)
253
- })
251
+ filter: <U extends keyof Encoded = never>(f: FilterArgs<Encoded, U>) => {
252
+ const filter = f
253
+ .filter
254
+ type M = U extends undefined ? Encoded : Pick<Encoded, U>
255
+ return resolveNamespace.pipe(Effect.flatMap((ns) =>
256
+ Effect
257
+ .sync(() => {
258
+ const q = buildWhereSQLQuery(
259
+ pgDialect,
260
+ idKey,
261
+ filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [],
262
+ tableName,
263
+ defaultValues,
264
+ f.select as
265
+ | NonEmptyReadonlyArray<
266
+ string | {
267
+ key: string
268
+ subKeys: readonly string[]
269
+ } | {
270
+ key: string
271
+ computed: ComputedProjectionIrExpression
272
+ }
273
+ >
274
+ | undefined,
275
+ f.order,
276
+ f.skip,
277
+ f.limit,
278
+ ns,
279
+ json
280
+ )
281
+ const nsPlaceholder = pgDialect.placeholder(q.params.length + 1)
282
+ const hasWhere = q.sql.includes("WHERE")
283
+ const nsSql = hasWhere
284
+ ? q.sql.replace("WHERE", `WHERE _namespace = ${nsPlaceholder} AND`)
285
+ : q.sql.replace(
286
+ `FROM "${tableName}"`,
287
+ `FROM "${tableName}" WHERE _namespace = ${nsPlaceholder}`
288
+ )
289
+ return { sql: nsSql, params: [...q.params, ns] }
290
+ })
291
+ .pipe(
292
+ Effect.tap((q) => logQuery(q)),
293
+ Effect.tap((q) => Effect.annotateCurrentSpan({ "db.query.text": q.sql })),
294
+ Effect.flatMap((q) =>
295
+ exec(q.sql, q.params).pipe(
296
+ Effect.flatMap((rows) => {
297
+ if (f.select) {
298
+ return Effect.succeed((rows as any[]).map((r) => {
299
+ const selected = parseSelectRow(r, idKey, {})
300
+ return {
301
+ ...Struct.pick(
302
+ defaultValues as any,
303
+ f.select!.filter((_) => typeof _ === "string") as never[]
304
+ ),
305
+ ...selected
306
+ } as M
307
+ }))
308
+ }
309
+ return Effect.map(
310
+ Effect.fromResult(decodeStoredMany(rows as any[], decodeRow)),
311
+ (decoded) => decoded as any as M[]
254
312
  )
255
- ),
256
- Effect.withSpan("PgSQL.filter [effect-app/infra/Store]", {
257
- attributes: { "repository.table_name": tableName, "repository.model_name": name }
258
- }, { captureStackTrace: false })
313
+ })
259
314
  )
260
- ))
261
- },
262
-
263
- set: (e) =>
264
- resolveAndSeed.pipe(Effect.flatMap((ns) =>
265
- setInternal(e, ns).pipe(
266
- Effect.withSpan("PgSQL.set [effect-app/infra/Store]", {
267
- attributes: { "repository.table_name": tableName, "repository.model_name": name, id: e[idKey] }
268
- }, { captureStackTrace: false })
269
- )
270
- )),
315
+ ),
316
+ annotateDb({
317
+ operation: "filter",
318
+ system: "postgresql",
319
+ collection: tableName,
320
+ namespace: ns,
321
+ entity: name
322
+ })
323
+ )
324
+ ))
325
+ },
271
326
 
272
- batchSet: (items) =>
273
- resolveAndSeed.pipe(Effect.flatMap((ns) =>
274
- bulkSetInternal(items, ns).pipe(
275
- Effect.withSpan("PgSQL.batchSet [effect-app/infra/Store]", {
276
- attributes: { "repository.table_name": tableName, "repository.model_name": name }
277
- }, { captureStackTrace: false })
278
- )
279
- )),
327
+ set: (e) =>
328
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
329
+ setInternal(e, ns).pipe(
330
+ annotateDb({
331
+ operation: "set",
332
+ system: "postgresql",
333
+ collection: tableName,
334
+ namespace: ns,
335
+ entity: name,
336
+ extra: { "app.entity.id": e[idKey] }
337
+ })
338
+ )
339
+ )),
280
340
 
281
- bulkSet: (items) =>
282
- resolveAndSeed.pipe(Effect.flatMap((ns) =>
283
- bulkSetInternal(items, ns).pipe(
284
- Effect.withSpan("PgSQL.bulkSet [effect-app/infra/Store]", {
285
- attributes: { "repository.table_name": tableName, "repository.model_name": name }
286
- }, { captureStackTrace: false })
287
- )
288
- )),
341
+ batchSet: (items) =>
342
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
343
+ bulkSetInternal(items, ns).pipe(
344
+ annotateDb({
345
+ operation: "batchSet",
346
+ system: "postgresql",
347
+ collection: tableName,
348
+ namespace: ns,
349
+ entity: name
350
+ })
351
+ )
352
+ )),
289
353
 
290
- batchRemove: (ids) => {
291
- const placeholders = ids.map((_, i) => `$${i + 1}`).join(", ")
292
- const nsPlaceholder = `$${ids.length + 1}`
293
- return resolveAndSeed.pipe(Effect.flatMap((ns) =>
294
- exec(
295
- `DELETE FROM "${tableName}" WHERE id IN (${placeholders}) AND _namespace = ${nsPlaceholder}`,
296
- [...ids, ns]
297
- )
298
- .pipe(
299
- Effect.asVoid,
300
- Effect.withSpan("PgSQL.batchRemove [effect-app/infra/Store]", {
301
- attributes: { "repository.table_name": tableName, "repository.model_name": name }
302
- }, { captureStackTrace: false })
303
- )
304
- ))
305
- },
354
+ bulkSet: (items) =>
355
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
356
+ bulkSetInternal(items, ns).pipe(
357
+ annotateDb({
358
+ operation: "bulkSet",
359
+ system: "postgresql",
360
+ collection: tableName,
361
+ namespace: ns,
362
+ entity: name
363
+ })
364
+ )
365
+ )),
306
366
 
307
- queryRaw: (query) =>
308
- s.all.pipe(
309
- Effect.map(query.memory),
310
- Effect.withSpan("PgSQL.queryRaw [effect-app/infra/Store]", {
311
- attributes: { "repository.table_name": tableName, "repository.model_name": name }
312
- }, { captureStackTrace: false })
367
+ batchRemove: (ids) => {
368
+ const placeholders = ids.map((_, i) => `$${i + 1}`).join(", ")
369
+ const nsPlaceholder = `$${ids.length + 1}`
370
+ return resolveNamespace.pipe(Effect.flatMap((ns) => {
371
+ const sqlText = `DELETE FROM "${tableName}" WHERE id IN (${placeholders}) AND _namespace = ${nsPlaceholder}`
372
+ return exec(sqlText, [...ids, ns])
373
+ .pipe(
374
+ Effect.asVoid,
375
+ annotateDb({
376
+ operation: "batchRemove",
377
+ system: "postgresql",
378
+ collection: tableName,
379
+ namespace: ns,
380
+ entity: name,
381
+ query: sqlText
382
+ })
313
383
  )
314
- }
384
+ }))
385
+ },
315
386
 
316
- // Eagerly seed primary namespace on initialization
317
- yield* seedNamespace("primary")
387
+ queryRaw: (query) =>
388
+ allStored.pipe(
389
+ Effect.map(query.memory),
390
+ annotateDb({
391
+ operation: "queryRaw",
392
+ system: "postgresql",
393
+ collection: tableName,
394
+ entity: name
395
+ })
396
+ )
397
+ }
318
398
 
319
- return s
320
- })
321
- }
322
- })
323
- }
399
+ // Eagerly seed primary namespace on initialization. A seed failure at
400
+ // construction is fatal (orDie); the per-call `seedNamespace` still
401
+ // surfaces DatabaseError to callers.
402
+ yield* seedNamespace("primary").pipe(Effect.orDie)
403
+
404
+ return s
405
+ })
406
+ }
407
+ })
324
408
 
325
409
  export function PgStoreLayer(cfg: StorageConfig) {
326
410
  return StoreMaker