@effect-app/infra 4.0.0-beta.99 → 4.0.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.
Files changed (486) hide show
  1. package/CHANGELOG.md +2901 -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 +240 -44
  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 -320
  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 +347 -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 +230 -155
  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 +308 -14
  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 +370 -99
  53. package/dist/Store/codeFilter.d.ts +5 -5
  54. package/dist/Store/codeFilter.d.ts.map +1 -1
  55. package/dist/Store/codeFilter.js +72 -23
  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 +257 -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 +277 -57
  169. package/src/Store/Cosmos.ts +597 -512
  170. package/src/Store/Disk.ts +145 -71
  171. package/src/Store/Memory.ts +419 -115
  172. package/src/Store/SQL/Pg.ts +352 -269
  173. package/src/Store/SQL/query.ts +368 -22
  174. package/src/Store/SQL.ts +742 -294
  175. package/src/Store/codeFilter.ts +79 -29
  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 +70 -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 +827 -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,51 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
 
3
- import { Effect, type NonEmptyReadonlyArray, Option, Struct } from "effect-app"
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"
3
+ import { isReadonlyArrayNonEmpty, type NonEmptyReadonlyArray } from "effect-app/Array"
4
+ import * as Effect from "effect-app/Effect"
5
+ import type { FieldValues } from "effect-app/Model/filter/types"
6
+ import type { ComputedProjectionIrExpression } from "effect-app/Model/query"
7
+ import * as Option from "effect-app/Option"
8
+ import { type FilterArgs, type PersistenceModelType, type StorageConfig, type Store, type StoreConfig, storeId, StoreMaker } from "effect-app/Store"
9
+ import { SqlClient } from "effect/sql"
10
+ import * as Struct from "effect/Struct"
11
+ import { DatabaseError, OptimisticConcurrencyException } from "../../errors.ts"
12
+ import { InfraLogger } from "../../logger.ts"
13
+ import { annotateDb } from "../../otel.ts"
14
+ import { decodeStoredMany, decodeStoredOption, makeJsonDocumentCodec, makeStoredDecode } from "../jsonDocument.ts"
15
+ import { makeETag, makeJsonLower, toJsonQueryValue } from "../utils.ts"
16
+ import { buildWhereSQLQuery, logQuery, pgDialect } from "./query.ts"
13
17
 
18
+ const sqlErrorMessage = (e: unknown) => (e as any)?.message ? String((e as any).message) : String(e)
19
+ const sqlIsTransient = (e: unknown) =>
20
+ /timeout|ETIMEDOUT|ECONNRESET|ECONNREFUSED|connection|deadlock|too many connections/i.test(sqlErrorMessage(e))
21
+ // Map a SqlError into a typed, serializable DatabaseError (instead of `.orDie`,
22
+ // which would turn it into an opaque, non-serializable defect).
23
+ const toDatabaseError = (e: unknown) =>
24
+ new DatabaseError({ message: `SQL request failed: ${sqlErrorMessage(e)}`, transient: sqlIsTransient(e), cause: e })
25
+ // withTransaction may re-raise setInternal's typed errors or add SqlError on begin/commit.
26
+ // Preserve DatabaseError / OCC by `_tag` (not instanceof — dual package instances break it);
27
+ // map residual SQL failures to DatabaseError.
28
+ const preserveStoreError = (e: unknown): DatabaseError | OptimisticConcurrencyException => {
29
+ if (e !== null && typeof e === "object" && "_tag" in e) {
30
+ if (e._tag === "DatabaseError") return e as DatabaseError
31
+ if (e._tag === "OptimisticConcurrencyException") return e as OptimisticConcurrencyException
32
+ }
33
+ return toDatabaseError(e)
34
+ }
35
+
36
+ /**
37
+ * Row -> raw stored JSON document. Decoding it is a separate step
38
+ * (`makeStoredDecode`), so a document `jitM` does not repair fails as a typed
39
+ * `S.SchemaError` rather than throwing out of here.
40
+ */
14
41
  const parseRow = <Encoded extends FieldValues>(
15
42
  row: { id: string; _etag: string | null; data: unknown },
16
43
  idKey: PropertyKey,
17
44
  defaultValues: Partial<Encoded>
18
45
  ): PersistenceModelType<Encoded> => {
19
46
  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>
47
+ const jsonDefaults = toJsonQueryValue(defaultValues) as Partial<Encoded>
48
+ return { ...jsonDefaults, ...data, [idKey]: row.id, _etag: row._etag ?? undefined } as PersistenceModelType<Encoded>
21
49
  }
22
50
 
23
51
  const parseSelectRow = (
@@ -37,290 +65,345 @@ const parseSelectRow = (
37
65
  return result
38
66
  }
39
67
 
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 ?? {}
68
+ const makePgStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
69
+ const sql = yield* SqlClient.SqlClient
70
+ return {
71
+ make: Effect.fnUntraced(function*<IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>(
72
+ name: string,
73
+ idKey: IdKey,
74
+ seed?: Effect.Effect<Iterable<Encoded>, E, R>,
75
+ config?: StoreConfig<Encoded>
76
+ ) {
77
+ type PM = PersistenceModelType<Encoded>
78
+ const tableName = `${prefix}${name}`
79
+ const json = makeJsonLower(config)
80
+ const defaultValues = json.toJson(config?.defaultValues ?? {}) as Partial<Encoded>
81
+ const codec = makeJsonDocumentCodec<Encoded>(config?.schema)
82
+ // read path: stored JSON -> defaultValues -> jitM -> JSON→Encoded decode
83
+ const decodeStored = makeStoredDecode<Encoded>(config?.schema, config?.jitM)
84
+ const decodeRow = (row: { id: string; _etag: string | null; data: unknown }) =>
85
+ decodeStored(parseRow<Encoded>(row, idKey, defaultValues))
54
86
 
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
- }))
87
+ const resolveNamespace = !config?.allowNamespace
88
+ ? Effect.succeed("primary")
89
+ : storeId.pipe(Effect.map((namespace) => {
90
+ if (namespace !== "primary" && !config.allowNamespace!(namespace)) {
91
+ throw new Error(`Namespace ${namespace} not allowed!`)
92
+ }
93
+ return namespace
94
+ }))
63
95
 
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))`
96
+ const ensureTable = sql
97
+ .unsafe(
98
+ `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))`
99
+ )
100
+ .pipe(
101
+ Effect.andThen(
102
+ sql.unsafe(
103
+ `CREATE TABLE IF NOT EXISTS "_migrations" (id TEXT NOT NULL, version TEXT NOT NULL, PRIMARY KEY (id, version))`
67
104
  )
68
- .pipe(Effect.orDie)
105
+ ),
106
+ Effect.orDie,
107
+ Effect.asVoid
108
+ )
69
109
 
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)
110
+ const toRow = (e: PM) => {
111
+ const newE = makeETag(codec.encode(e))
112
+ const id = newE[idKey] as string
113
+ const { _etag, [idKey]: _id, ...rest } = newE as any
114
+ const data = JSON.stringify(rest)
115
+ return { id, _etag: newE._etag!, data, item: codec.decode(newE) }
116
+ }
80
117
 
81
- const seedMarkerId = `__seed_marker__`
118
+ const exec = (query: string, params?: readonly unknown[]) =>
119
+ sql.unsafe(query, params as any).pipe(Effect.mapError(toDatabaseError))
82
120
 
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
121
+ const setInternal = Effect.fnUntraced(function*(e: PM, ns: string) {
122
+ const row = toRow(e)
123
+ if (e._etag) {
124
+ yield* exec(
125
+ `UPDATE "${tableName}" SET _etag = $1, data = $2 WHERE id = $3 AND _etag = $4 AND _namespace = $5`,
126
+ [row._etag, row.data, row.id, e._etag, ns]
127
+ )
128
+ const existing = yield* exec(
129
+ `SELECT _etag FROM "${tableName}" WHERE id = $1 AND _namespace = $2`,
130
+ [row.id, ns]
131
+ )
132
+ const current = (existing as any[])[0]
133
+ if (!current || current._etag !== row._etag) {
134
+ if (current) {
135
+ return yield* new OptimisticConcurrencyException({
136
+ type: name,
137
+ id: row.id,
138
+ current: current._etag,
139
+ found: e._etag,
140
+ code: 412
141
+ })
142
+ }
143
+ return yield* new OptimisticConcurrencyException({
144
+ type: name,
145
+ id: row.id,
146
+ current: "",
147
+ found: e._etag,
148
+ code: 404
121
149
  })
150
+ }
151
+ } else {
152
+ yield* exec(
153
+ `INSERT INTO "${tableName}" (id, _namespace, _etag, data) VALUES ($1, $2, $3, $4)`,
154
+ [row.id, ns, row._etag, row.data]
155
+ )
156
+ }
157
+ return row.item
158
+ })
122
159
 
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
- )
160
+ const bulkSetInternal = (items: NonEmptyReadonlyArray<PM>, ns: string) =>
161
+ sql
162
+ .withTransaction(Effect.forEach(items, (e) => setInternal(e, ns)))
163
+ .pipe(
164
+ Effect.mapError(preserveStoreError),
165
+ Effect.map((_) => _ as unknown as NonEmptyReadonlyArray<PM>)
166
+ )
130
167
 
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
- )
168
+ const ctx = yield* Effect.context<R>()
169
+ const seedCache = new Map<string, Effect.Effect<void, DatabaseError>>()
170
+ const makeSeedEffect = Effect.fnUntraced(function*(ns: string) {
171
+ yield* ensureTable
172
+ if (!seed) return
173
+ const existing = yield* exec(
174
+ `SELECT id FROM "_migrations" WHERE id = $1 AND version = $2`,
175
+ [`${tableName}::${ns}`, tableName]
176
+ )
177
+ if ((existing as any[]).length > 0) return
178
+ yield* InfraLogger.logInfo(`Seeding data for ${name} (namespace: ${ns})`)
179
+ const items = yield* seed.pipe(Effect.provide(ctx), Effect.orDie)
180
+ const ne = Option.liftPredicate(isReadonlyArrayNonEmpty)([...items])
181
+ // Seed inserts are not concurrent; OCC here is a programming defect.
182
+ if (Option.isSome(ne)) {
183
+ yield* bulkSetInternal(ne.value, ns).pipe(
184
+ Effect.catchTag("OptimisticConcurrencyException", Effect.die)
185
+ )
186
+ }
187
+ yield* exec(
188
+ `INSERT INTO "_migrations" (id, version) VALUES ($1, $2)`,
189
+ [`${tableName}::${ns}`, tableName]
190
+ )
191
+ })
192
+ const seedNamespace = (ns: string) => {
193
+ let cached = seedCache.get(ns)
194
+ if (!cached) {
195
+ cached = Effect.cached(Effect.uninterruptible(makeSeedEffect(ns))).pipe(Effect.runSync)
196
+ seedCache.set(ns, cached)
197
+ }
198
+ return cached
199
+ }
200
+ const selectAllSql = `SELECT id, _etag, data FROM "${tableName}" WHERE _namespace = $1`
201
+ const allStored = resolveNamespace.pipe(
202
+ Effect.flatMap((ns) =>
203
+ exec(selectAllSql, [ns]).pipe(
204
+ Effect.map((rows) => (rows as any[]).map((row) => parseRow<Encoded>(row, idKey, defaultValues)))
205
+ )
206
+ )
207
+ )
208
+
209
+ const s: Store<IdKey, Encoded> = {
210
+ seedNamespace: (ns) => seedNamespace(ns),
211
+
212
+ all: resolveNamespace.pipe(
213
+ Effect.flatMap((ns) => {
214
+ return exec(selectAllSql, [ns])
138
215
  .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
- )
216
+ Effect.flatMap((rows) => Effect.fromResult(decodeStoredMany(rows as any[], decodeRow))),
217
+ annotateDb({
218
+ operation: "all",
219
+ system: "postgresql",
220
+ collection: tableName,
221
+ namespace: ns,
222
+ entity: name,
223
+ query: selectAllSql
158
224
  })
159
225
  )
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
226
  })
169
- const resolveAndSeed = resolveNamespace.pipe(
170
- Effect.tap((ns) => seedNamespace(ns))
171
- )
227
+ ),
172
228
 
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])
229
+ find: (id) =>
230
+ resolveNamespace.pipe(Effect
231
+ .flatMap((ns) => {
232
+ const sqlText = `SELECT id, _etag, data FROM "${tableName}" WHERE id = $1 AND _namespace = $2`
233
+ return exec(sqlText, [id, ns])
176
234
  .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 })
235
+ Effect.flatMap((rows) =>
236
+ Effect.fromResult(decodeStoredOption(Option.fromNullishOr((rows as any[])[0]), decodeRow))
237
+ ),
238
+ annotateDb({
239
+ operation: "find",
240
+ system: "postgresql",
241
+ collection: tableName,
242
+ namespace: ns,
243
+ entity: name,
244
+ query: sqlText,
245
+ extra: { "app.entity.id": id }
246
+ })
185
247
  )
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
- )),
248
+ })),
204
249
 
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
- })
250
+ filter: <U extends keyof Encoded = never>(f: FilterArgs<Encoded, U>) => {
251
+ const filter = f
252
+ .filter
253
+ type M = U extends undefined ? Encoded : Pick<Encoded, U>
254
+ return resolveNamespace.pipe(Effect.flatMap((ns) =>
255
+ Effect
256
+ .sync(() => {
257
+ const q = buildWhereSQLQuery(
258
+ pgDialect,
259
+ idKey,
260
+ filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [],
261
+ tableName,
262
+ defaultValues,
263
+ f.select as
264
+ | NonEmptyReadonlyArray<
265
+ string | {
266
+ key: string
267
+ subKeys: readonly string[]
268
+ } | {
269
+ key: string
270
+ computed: ComputedProjectionIrExpression
271
+ }
272
+ >
273
+ | undefined,
274
+ f.order,
275
+ f.skip,
276
+ f.limit,
277
+ ns,
278
+ json
279
+ )
280
+ const nsPlaceholder = pgDialect.placeholder(q.params.length + 1)
281
+ const hasWhere = q.sql.includes("WHERE")
282
+ const nsSql = hasWhere
283
+ ? q.sql.replace("WHERE", `WHERE _namespace = ${nsPlaceholder} AND`)
284
+ : q.sql.replace(
285
+ `FROM "${tableName}"`,
286
+ `FROM "${tableName}" WHERE _namespace = ${nsPlaceholder}`
287
+ )
288
+ return { sql: nsSql, params: [...q.params, ns] }
289
+ })
290
+ .pipe(
291
+ Effect.tap((q) => logQuery(q)),
292
+ Effect.tap((q) => Effect.annotateCurrentSpan({ "db.query.text": q.sql })),
293
+ Effect.flatMap((q) =>
294
+ exec(q.sql, q.params).pipe(
295
+ Effect.flatMap((rows) => {
296
+ if (f.select) {
297
+ return Effect.succeed((rows as any[]).map((r) => {
298
+ const selected = parseSelectRow(r, idKey, {})
299
+ return {
300
+ ...Struct.pick(
301
+ defaultValues as any,
302
+ f.select!.filter((_) => typeof _ === "string") as never[]
303
+ ),
304
+ ...selected
305
+ } as M
306
+ }))
307
+ }
308
+ return Effect.map(
309
+ Effect.fromResult(decodeStoredMany(rows as any[], decodeRow)),
310
+ (decoded) => decoded as any as M[]
254
311
  )
255
- ),
256
- Effect.withSpan("PgSQL.filter [effect-app/infra/Store]", {
257
- attributes: { "repository.table_name": tableName, "repository.model_name": name }
258
- }, { captureStackTrace: false })
312
+ })
259
313
  )
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
- )),
314
+ ),
315
+ annotateDb({
316
+ operation: "filter",
317
+ system: "postgresql",
318
+ collection: tableName,
319
+ namespace: ns,
320
+ entity: name
321
+ })
322
+ )
323
+ ))
324
+ },
271
325
 
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
- )),
326
+ set: (e) =>
327
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
328
+ setInternal(e, ns).pipe(
329
+ annotateDb({
330
+ operation: "set",
331
+ system: "postgresql",
332
+ collection: tableName,
333
+ namespace: ns,
334
+ entity: name,
335
+ extra: { "app.entity.id": e[idKey] }
336
+ })
337
+ )
338
+ )),
280
339
 
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
- )),
340
+ batchSet: (items) =>
341
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
342
+ bulkSetInternal(items, ns).pipe(
343
+ annotateDb({
344
+ operation: "batchSet",
345
+ system: "postgresql",
346
+ collection: tableName,
347
+ namespace: ns,
348
+ entity: name
349
+ })
350
+ )
351
+ )),
289
352
 
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
- },
353
+ bulkSet: (items) =>
354
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
355
+ bulkSetInternal(items, ns).pipe(
356
+ annotateDb({
357
+ operation: "bulkSet",
358
+ system: "postgresql",
359
+ collection: tableName,
360
+ namespace: ns,
361
+ entity: name
362
+ })
363
+ )
364
+ )),
306
365
 
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 })
366
+ batchRemove: (ids) => {
367
+ const placeholders = ids.map((_, i) => `$${i + 1}`).join(", ")
368
+ const nsPlaceholder = `$${ids.length + 1}`
369
+ return resolveNamespace.pipe(Effect.flatMap((ns) => {
370
+ const sqlText = `DELETE FROM "${tableName}" WHERE id IN (${placeholders}) AND _namespace = ${nsPlaceholder}`
371
+ return exec(sqlText, [...ids, ns])
372
+ .pipe(
373
+ Effect.asVoid,
374
+ annotateDb({
375
+ operation: "batchRemove",
376
+ system: "postgresql",
377
+ collection: tableName,
378
+ namespace: ns,
379
+ entity: name,
380
+ query: sqlText
381
+ })
313
382
  )
314
- }
383
+ }))
384
+ },
315
385
 
316
- // Eagerly seed primary namespace on initialization
317
- yield* seedNamespace("primary")
386
+ queryRaw: (query) =>
387
+ allStored.pipe(
388
+ Effect.map(query.memory),
389
+ annotateDb({
390
+ operation: "queryRaw",
391
+ system: "postgresql",
392
+ collection: tableName,
393
+ entity: name
394
+ })
395
+ )
396
+ }
318
397
 
319
- return s
320
- })
321
- }
322
- })
323
- }
398
+ // Eagerly seed primary namespace on initialization. A seed failure at
399
+ // construction is fatal (orDie); the per-call `seedNamespace` still
400
+ // surfaces DatabaseError to callers.
401
+ yield* seedNamespace("primary").pipe(Effect.orDie)
402
+
403
+ return s
404
+ })
405
+ }
406
+ })
324
407
 
325
408
  export function PgStoreLayer(cfg: StorageConfig) {
326
409
  return StoreMaker