@effect-app/infra 4.0.0-beta.26 → 4.0.0-beta.261

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 (505) hide show
  1. package/CHANGELOG.md +1973 -0
  2. package/_check.sh +1 -1
  3. package/dist/CUPS.d.ts +30 -11
  4. package/dist/CUPS.d.ts.map +1 -1
  5. package/dist/CUPS.js +35 -14
  6. package/dist/ClusterCosmos.d.ts +64 -0
  7. package/dist/ClusterCosmos.d.ts.map +1 -0
  8. package/dist/ClusterCosmos.js +501 -0
  9. package/dist/ClusterServiceBus.d.ts +67 -0
  10. package/dist/ClusterServiceBus.d.ts.map +1 -0
  11. package/dist/ClusterServiceBus.js +82 -0
  12. package/dist/ContextProvider.d.ts +34 -0
  13. package/dist/ContextProvider.d.ts.map +1 -0
  14. package/dist/ContextProvider.js +40 -0
  15. package/dist/Emailer/Sendgrid.d.ts +111 -147
  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 +2 -2
  19. package/dist/Emailer/fake.d.ts.map +1 -1
  20. package/dist/Emailer/fake.js +4 -4
  21. package/dist/MainFiberSet.d.ts +12 -9
  22. package/dist/MainFiberSet.d.ts.map +1 -1
  23. package/dist/MainFiberSet.js +10 -6
  24. package/dist/QueueMaker/SQLQueue.d.ts +8 -9
  25. package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
  26. package/dist/QueueMaker/SQLQueue.js +138 -120
  27. package/dist/QueueMaker/errors.d.ts +5 -3
  28. package/dist/QueueMaker/errors.d.ts.map +1 -1
  29. package/dist/QueueMaker/errors.js +4 -2
  30. package/dist/QueueMaker/memQueue.d.ts +10 -6
  31. package/dist/QueueMaker/memQueue.d.ts.map +1 -1
  32. package/dist/QueueMaker/memQueue.js +84 -68
  33. package/dist/QueueMaker/sbqueue.d.ts +9 -5
  34. package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
  35. package/dist/QueueMaker/sbqueue.js +60 -58
  36. package/dist/RequestFiberSet.d.ts +10 -7
  37. package/dist/RequestFiberSet.d.ts.map +1 -1
  38. package/dist/RequestFiberSet.js +13 -8
  39. package/dist/SQL/Model.d.ts +468 -0
  40. package/dist/SQL/Model.d.ts.map +1 -0
  41. package/dist/SQL/Model.js +469 -0
  42. package/dist/SQL.d.ts +2 -0
  43. package/dist/SQL.d.ts.map +1 -0
  44. package/dist/{adapters/SQL.js → SQL.js} +1 -1
  45. package/dist/ServiceBus.d.ts +61 -0
  46. package/dist/ServiceBus.d.ts.map +1 -0
  47. package/dist/ServiceBus.js +108 -0
  48. package/dist/Store/Cosmos/query.d.ts +15 -4
  49. package/dist/Store/Cosmos/query.d.ts.map +1 -1
  50. package/dist/Store/Cosmos/query.js +179 -41
  51. package/dist/Store/Cosmos.d.ts +3 -3
  52. package/dist/Store/Cosmos.d.ts.map +1 -1
  53. package/dist/Store/Cosmos.js +344 -246
  54. package/dist/Store/Disk.d.ts +5 -5
  55. package/dist/Store/Disk.d.ts.map +1 -1
  56. package/dist/Store/Disk.js +78 -38
  57. package/dist/Store/Memory.d.ts +7 -10
  58. package/dist/Store/Memory.d.ts.map +1 -1
  59. package/dist/Store/Memory.js +326 -66
  60. package/dist/Store/SQL/Pg.d.ts +4 -0
  61. package/dist/Store/SQL/Pg.d.ts.map +1 -0
  62. package/dist/Store/SQL/Pg.js +232 -0
  63. package/dist/Store/SQL/query.d.ts +49 -0
  64. package/dist/Store/SQL/query.d.ts.map +1 -0
  65. package/dist/Store/SQL/query.js +527 -0
  66. package/dist/Store/SQL.d.ts +21 -0
  67. package/dist/Store/SQL.d.ts.map +1 -0
  68. package/dist/Store/SQL.js +449 -0
  69. package/dist/Store/codeFilter.d.ts +5 -5
  70. package/dist/Store/codeFilter.d.ts.map +1 -1
  71. package/dist/Store/codeFilter.js +6 -3
  72. package/dist/Store/index.d.ts +7 -5
  73. package/dist/Store/index.d.ts.map +1 -1
  74. package/dist/Store/index.js +18 -5
  75. package/dist/Store/utils.d.ts +4 -3
  76. package/dist/Store/utils.d.ts.map +1 -1
  77. package/dist/Store/utils.js +5 -5
  78. package/dist/WorkflowEngineCosmos.d.ts +29 -0
  79. package/dist/WorkflowEngineCosmos.d.ts.map +1 -0
  80. package/dist/WorkflowEngineCosmos.js +521 -0
  81. package/dist/WorkflowEngineSqlite.d.ts +24 -0
  82. package/dist/WorkflowEngineSqlite.d.ts.map +1 -0
  83. package/dist/WorkflowEngineSqlite.js +550 -0
  84. package/dist/arbs.d.ts +2 -2
  85. package/dist/arbs.d.ts.map +1 -1
  86. package/dist/arbs.js +5 -3
  87. package/dist/codec.d.ts +5 -0
  88. package/dist/codec.d.ts.map +1 -0
  89. package/dist/codec.js +5 -0
  90. package/dist/cosmos-client.d.ts +16 -0
  91. package/dist/cosmos-client.d.ts.map +1 -0
  92. package/dist/cosmos-client.js +11 -0
  93. package/dist/errorReporter.d.ts +7 -5
  94. package/dist/errorReporter.d.ts.map +1 -1
  95. package/dist/errorReporter.js +23 -27
  96. package/dist/errors.d.ts +1 -1
  97. package/dist/fileUtil.d.ts +2 -2
  98. package/dist/fileUtil.d.ts.map +1 -1
  99. package/dist/fileUtil.js +2 -2
  100. package/dist/index.d.ts +3 -2
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +3 -2
  103. package/dist/internal/RequestContextMiddleware.d.ts +5 -0
  104. package/dist/internal/RequestContextMiddleware.d.ts.map +1 -0
  105. package/dist/internal/RequestContextMiddleware.js +45 -0
  106. package/dist/internal/auth.d.ts +53 -0
  107. package/dist/internal/auth.d.ts.map +1 -0
  108. package/dist/internal/auth.js +180 -0
  109. package/dist/internal/events.d.ts +11 -0
  110. package/dist/internal/events.d.ts.map +1 -0
  111. package/dist/internal/events.js +49 -0
  112. package/dist/internal/health.d.ts +3 -0
  113. package/dist/internal/health.d.ts.map +1 -0
  114. package/dist/internal/health.js +5 -0
  115. package/dist/layerUtils.d.ts +32 -0
  116. package/dist/layerUtils.d.ts.map +1 -0
  117. package/dist/layerUtils.js +17 -0
  118. package/dist/logger/jsonLogger.d.ts +2 -2
  119. package/dist/logger/jsonLogger.d.ts.map +1 -1
  120. package/dist/logger/jsonLogger.js +5 -3
  121. package/dist/logger/logFmtLogger.d.ts +2 -2
  122. package/dist/logger/logFmtLogger.d.ts.map +1 -1
  123. package/dist/logger/logFmtLogger.js +3 -3
  124. package/dist/logger/shared.d.ts +3 -3
  125. package/dist/logger/shared.d.ts.map +1 -1
  126. package/dist/logger/shared.js +5 -5
  127. package/dist/logger.d.ts +1 -1
  128. package/dist/logger.d.ts.map +1 -1
  129. package/dist/memQueue.d.ts +15 -0
  130. package/dist/memQueue.d.ts.map +1 -0
  131. package/dist/memQueue.js +21 -0
  132. package/dist/middlewares.d.ts +10 -0
  133. package/dist/middlewares.d.ts.map +1 -0
  134. package/dist/{api/middlewares.js → middlewares.js} +1 -1
  135. package/dist/mongo-client.d.ts +11 -0
  136. package/dist/mongo-client.d.ts.map +1 -0
  137. package/dist/mongo-client.js +15 -0
  138. package/dist/otel.d.ts +75 -0
  139. package/dist/otel.d.ts.map +1 -0
  140. package/dist/otel.js +65 -0
  141. package/dist/rateLimit.d.ts +12 -4
  142. package/dist/rateLimit.d.ts.map +1 -1
  143. package/dist/rateLimit.js +7 -12
  144. package/dist/redis-client.d.ts +42 -0
  145. package/dist/redis-client.d.ts.map +1 -0
  146. package/dist/redis-client.js +98 -0
  147. package/dist/reportError.d.ts +4 -0
  148. package/dist/reportError.d.ts.map +1 -0
  149. package/dist/reportError.js +28 -0
  150. package/dist/routing/middleware/RouterMiddleware.d.ts +16 -0
  151. package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
  152. package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
  153. package/dist/routing/middleware/middleware.d.ts +48 -0
  154. package/dist/routing/middleware/middleware.d.ts.map +1 -0
  155. package/dist/routing/middleware/middleware.js +128 -0
  156. package/dist/routing/middleware.d.ts +3 -0
  157. package/dist/routing/middleware.d.ts.map +1 -0
  158. package/dist/{api/routing → routing}/middleware.js +1 -2
  159. package/dist/routing/schema/jwt.d.ts +4 -0
  160. package/dist/routing/schema/jwt.d.ts.map +1 -0
  161. package/dist/routing/schema/jwt.js +13 -0
  162. package/dist/routing/tsort.d.ts +8 -0
  163. package/dist/routing/tsort.d.ts.map +1 -0
  164. package/dist/routing/tsort.js +51 -0
  165. package/dist/routing/utils.d.ts +19 -0
  166. package/dist/routing/utils.d.ts.map +1 -0
  167. package/dist/routing/utils.js +45 -0
  168. package/dist/routing.d.ts +184 -0
  169. package/dist/routing.d.ts.map +1 -0
  170. package/dist/routing.js +236 -0
  171. package/dist/test.d.ts +3 -3
  172. package/dist/test.d.ts.map +1 -1
  173. package/dist/test.js +2 -2
  174. package/dist/util.d.ts +3 -0
  175. package/dist/util.d.ts.map +1 -0
  176. package/dist/util.js +14 -0
  177. package/dist/vitest.d.ts +1 -1
  178. package/docs/cluster-storage.md +26 -0
  179. package/docs/workflow-engine.md +262 -0
  180. package/examples/query.ts +47 -39
  181. package/package.json +31 -345
  182. package/run.sh +1 -0
  183. package/src/CUPS.ts +52 -13
  184. package/src/ClusterCosmos.ts +984 -0
  185. package/src/ClusterServiceBus.ts +242 -0
  186. package/src/{api/ContextProvider.ts → ContextProvider.ts} +19 -16
  187. package/src/Emailer/Sendgrid.ts +82 -59
  188. package/src/Emailer/fake.ts +3 -3
  189. package/src/MainFiberSet.ts +12 -10
  190. package/src/QueueMaker/SQLQueue.ts +153 -156
  191. package/src/QueueMaker/errors.ts +3 -1
  192. package/src/QueueMaker/memQueue.ts +113 -107
  193. package/src/QueueMaker/sbqueue.ts +78 -90
  194. package/src/RequestFiberSet.ts +13 -8
  195. package/src/{adapters/SQL → SQL}/Model.ts +42 -41
  196. package/src/ServiceBus.ts +219 -0
  197. package/src/Store/Cosmos/query.ts +216 -52
  198. package/src/Store/Cosmos.ts +493 -353
  199. package/src/Store/Disk.ts +109 -69
  200. package/src/Store/Memory.ts +365 -96
  201. package/src/Store/SQL/Pg.ts +363 -0
  202. package/src/Store/SQL/query.ts +603 -0
  203. package/src/Store/SQL.ts +735 -0
  204. package/src/Store/codeFilter.ts +8 -5
  205. package/src/Store/index.ts +21 -6
  206. package/src/Store/utils.ts +26 -24
  207. package/src/WorkflowEngineCosmos.ts +719 -0
  208. package/src/WorkflowEngineSqlite.ts +813 -0
  209. package/src/arbs.ts +5 -3
  210. package/src/{adapters/cosmos-client.ts → cosmos-client.ts} +5 -3
  211. package/src/errorReporter.ts +66 -76
  212. package/src/fileUtil.ts +1 -1
  213. package/src/index.ts +2 -1
  214. package/src/{api/internal → internal}/RequestContextMiddleware.ts +23 -6
  215. package/src/internal/auth.ts +272 -0
  216. package/src/{api/internal → internal}/events.ts +22 -13
  217. package/src/{api/layerUtils.ts → layerUtils.ts} +14 -10
  218. package/src/logger/jsonLogger.ts +4 -2
  219. package/src/logger/logFmtLogger.ts +2 -2
  220. package/src/logger/shared.ts +5 -4
  221. package/src/{adapters/memQueue.ts → memQueue.ts} +5 -4
  222. package/src/{adapters/mongo-client.ts → mongo-client.ts} +4 -2
  223. package/src/otel.ts +152 -0
  224. package/src/rateLimit.ts +34 -23
  225. package/src/{adapters/redis-client.ts → redis-client.ts} +7 -3
  226. package/src/{api/reportError.ts → reportError.ts} +3 -2
  227. package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +5 -4
  228. package/src/{api/routing → routing}/middleware/middleware.ts +62 -17
  229. package/src/routing/middleware.ts +4 -0
  230. package/src/{api/routing → routing}/schema/jwt.ts +2 -1
  231. package/src/{api/routing → routing}/utils.ts +2 -1
  232. package/src/routing.ts +768 -0
  233. package/src/test.ts +2 -2
  234. package/test/auth.test.ts +101 -0
  235. package/test/cluster-cosmos.test.ts +590 -0
  236. package/test/cluster-servicebus.test.ts +180 -0
  237. package/test/cluster-sqlite.test.ts +207 -0
  238. package/test/contextProvider.test.ts +15 -12
  239. package/test/controller.test.ts +28 -32
  240. package/test/cosmos-query.test.ts +159 -0
  241. package/test/dist/_check-agg-infer.test-d.d.ts +2 -0
  242. package/test/dist/_check-agg-infer.test-d.d.ts.map +1 -0
  243. package/test/dist/_check-agg-infer.test-d.js +19 -0
  244. package/test/dist/_check-proj-infer.test-d.d.ts +2 -0
  245. package/test/dist/_check-proj-infer.test-d.d.ts.map +1 -0
  246. package/test/dist/_check-proj-infer.test-d.js +16 -0
  247. package/test/dist/_check-tighten.test-d.d.ts +2 -0
  248. package/test/dist/_check-tighten.test-d.d.ts.map +1 -0
  249. package/test/dist/_check-tighten.test-d.js +21 -0
  250. package/test/dist/auth.test.d.ts.map +1 -0
  251. package/test/dist/cluster-cosmos.test.d.ts.map +1 -0
  252. package/test/dist/cluster-servicebus.test.d.ts.map +1 -0
  253. package/test/dist/cluster-sqlite.test.d.ts.map +1 -0
  254. package/test/dist/contextProvider.test.d.ts.map +1 -1
  255. package/test/dist/controller.test.d.ts.map +1 -1
  256. package/test/dist/cosmos-query.test.d.ts.map +1 -0
  257. package/test/dist/date-query.test.d.ts.map +1 -0
  258. package/test/dist/fixtures.d.ts +30 -12
  259. package/test/dist/fixtures.d.ts.map +1 -1
  260. package/test/dist/fixtures.js +17 -10
  261. package/test/dist/query.test.d.ts.map +1 -1
  262. package/test/dist/rawQuery.test.d.ts.map +1 -1
  263. package/test/dist/repository-ext.test.d.ts.map +1 -0
  264. package/test/dist/requires.test.d.ts.map +1 -1
  265. package/test/dist/router-generator.test.d.ts.map +1 -0
  266. package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
  267. package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
  268. package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
  269. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  270. package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
  271. package/test/dist/sql-store.test.d.ts.map +1 -0
  272. package/test/dist/workflow-engine-cosmos.test.d.ts.map +1 -0
  273. package/test/dist/workflow-engine-sqlite.test.d.ts.map +1 -0
  274. package/test/fixtures.ts +16 -9
  275. package/test/layerUtils.test.ts +2 -2
  276. package/test/query.test.ts +905 -40
  277. package/test/rawQuery.test.ts +340 -22
  278. package/test/repository-ext.test.ts +62 -0
  279. package/test/requires.test.ts +10 -5
  280. package/test/router-generator.test.ts +187 -0
  281. package/test/routing-interruptibility.test.ts +66 -0
  282. package/test/rpc-context-map-streaming.test.ts +262 -0
  283. package/test/rpc-e2e-invalidation.test.ts +256 -0
  284. package/test/rpc-multi-middleware.test.ts +85 -10
  285. package/test/rpc-stream-fullstack.test.ts +304 -0
  286. package/test/sql-store.test.ts +1711 -0
  287. package/test/validateSample.test.ts +26 -14
  288. package/test/workflow-engine-cosmos.test.ts +354 -0
  289. package/test/workflow-engine-sqlite.test.ts +299 -0
  290. package/tsconfig.examples.json +1 -1
  291. package/tsconfig.json +2 -1
  292. package/tsconfig.json.bak +2 -2
  293. package/tsconfig.src.json +35 -35
  294. package/tsconfig.test.json +2 -2
  295. package/dist/Emailer/service.d.ts +0 -55
  296. package/dist/Emailer/service.d.ts.map +0 -1
  297. package/dist/Emailer/service.js +0 -6
  298. package/dist/Emailer.d.ts +0 -2
  299. package/dist/Emailer.d.ts.map +0 -1
  300. package/dist/Emailer.js +0 -2
  301. package/dist/Model/Repository/ext.d.ts +0 -41
  302. package/dist/Model/Repository/ext.d.ts.map +0 -1
  303. package/dist/Model/Repository/ext.js +0 -65
  304. package/dist/Model/Repository/internal/internal.d.ts +0 -59
  305. package/dist/Model/Repository/internal/internal.d.ts.map +0 -1
  306. package/dist/Model/Repository/internal/internal.js +0 -316
  307. package/dist/Model/Repository/legacy.d.ts +0 -19
  308. package/dist/Model/Repository/legacy.d.ts.map +0 -1
  309. package/dist/Model/Repository/legacy.js +0 -2
  310. package/dist/Model/Repository/makeRepo.d.ts +0 -49
  311. package/dist/Model/Repository/makeRepo.d.ts.map +0 -1
  312. package/dist/Model/Repository/makeRepo.js +0 -24
  313. package/dist/Model/Repository/service.d.ts +0 -89
  314. package/dist/Model/Repository/service.d.ts.map +0 -1
  315. package/dist/Model/Repository/service.js +0 -2
  316. package/dist/Model/Repository/validation.d.ts +0 -42
  317. package/dist/Model/Repository/validation.d.ts.map +0 -1
  318. package/dist/Model/Repository/validation.js +0 -32
  319. package/dist/Model/Repository.d.ts +0 -6
  320. package/dist/Model/Repository.d.ts.map +0 -1
  321. package/dist/Model/Repository.js +0 -6
  322. package/dist/Model/dsl.d.ts +0 -32
  323. package/dist/Model/dsl.d.ts.map +0 -1
  324. package/dist/Model/dsl.js +0 -44
  325. package/dist/Model/filter/filterApi.d.ts +0 -30
  326. package/dist/Model/filter/filterApi.d.ts.map +0 -1
  327. package/dist/Model/filter/filterApi.js +0 -2
  328. package/dist/Model/filter/types/errors.d.ts +0 -29
  329. package/dist/Model/filter/types/errors.d.ts.map +0 -1
  330. package/dist/Model/filter/types/errors.js +0 -2
  331. package/dist/Model/filter/types/fields.d.ts +0 -15
  332. package/dist/Model/filter/types/fields.d.ts.map +0 -1
  333. package/dist/Model/filter/types/fields.js +0 -2
  334. package/dist/Model/filter/types/path/common.d.ts +0 -316
  335. package/dist/Model/filter/types/path/common.d.ts.map +0 -1
  336. package/dist/Model/filter/types/path/common.js +0 -2
  337. package/dist/Model/filter/types/path/eager.d.ts +0 -95
  338. package/dist/Model/filter/types/path/eager.d.ts.map +0 -1
  339. package/dist/Model/filter/types/path/eager.js +0 -31
  340. package/dist/Model/filter/types/path/index.d.ts +0 -4
  341. package/dist/Model/filter/types/path/index.d.ts.map +0 -1
  342. package/dist/Model/filter/types/path/index.js +0 -3
  343. package/dist/Model/filter/types/utils.d.ts +0 -79
  344. package/dist/Model/filter/types/utils.d.ts.map +0 -1
  345. package/dist/Model/filter/types/utils.js +0 -2
  346. package/dist/Model/filter/types/validator.d.ts +0 -30
  347. package/dist/Model/filter/types/validator.d.ts.map +0 -1
  348. package/dist/Model/filter/types/validator.js +0 -2
  349. package/dist/Model/filter/types.d.ts +0 -5
  350. package/dist/Model/filter/types.d.ts.map +0 -1
  351. package/dist/Model/filter/types.js +0 -7
  352. package/dist/Model/query/dsl.d.ts +0 -248
  353. package/dist/Model/query/dsl.d.ts.map +0 -1
  354. package/dist/Model/query/dsl.js +0 -104
  355. package/dist/Model/query/new-kid-interpreter.d.ts +0 -28
  356. package/dist/Model/query/new-kid-interpreter.d.ts.map +0 -1
  357. package/dist/Model/query/new-kid-interpreter.js +0 -165
  358. package/dist/Model/query.d.ts +0 -15
  359. package/dist/Model/query.d.ts.map +0 -1
  360. package/dist/Model/query.js +0 -3
  361. package/dist/Model.d.ts +0 -4
  362. package/dist/Model.d.ts.map +0 -1
  363. package/dist/Model.js +0 -4
  364. package/dist/Operations.d.ts +0 -55
  365. package/dist/Operations.d.ts.map +0 -1
  366. package/dist/Operations.js +0 -102
  367. package/dist/OperationsRepo.d.ts +0 -41
  368. package/dist/OperationsRepo.d.ts.map +0 -1
  369. package/dist/OperationsRepo.js +0 -14
  370. package/dist/QueueMaker/service.d.ts +0 -11
  371. package/dist/QueueMaker/service.d.ts.map +0 -1
  372. package/dist/QueueMaker/service.js +0 -4
  373. package/dist/RequestContext.d.ts +0 -63
  374. package/dist/RequestContext.d.ts.map +0 -1
  375. package/dist/RequestContext.js +0 -49
  376. package/dist/Store/ContextMapContainer.d.ts +0 -14
  377. package/dist/Store/ContextMapContainer.d.ts.map +0 -1
  378. package/dist/Store/ContextMapContainer.js +0 -16
  379. package/dist/Store/service.d.ts +0 -108
  380. package/dist/Store/service.d.ts.map +0 -1
  381. package/dist/Store/service.js +0 -71
  382. package/dist/Store.d.ts +0 -2
  383. package/dist/Store.d.ts.map +0 -1
  384. package/dist/Store.js +0 -2
  385. package/dist/adapters/SQL/Model.d.ts +0 -479
  386. package/dist/adapters/SQL/Model.d.ts.map +0 -1
  387. package/dist/adapters/SQL/Model.js +0 -478
  388. package/dist/adapters/SQL.d.ts +0 -2
  389. package/dist/adapters/SQL.d.ts.map +0 -1
  390. package/dist/adapters/ServiceBus.d.ts +0 -58
  391. package/dist/adapters/ServiceBus.d.ts.map +0 -1
  392. package/dist/adapters/ServiceBus.js +0 -99
  393. package/dist/adapters/cosmos-client.d.ts +0 -14
  394. package/dist/adapters/cosmos-client.d.ts.map +0 -1
  395. package/dist/adapters/cosmos-client.js +0 -9
  396. package/dist/adapters/index.d.ts +0 -2
  397. package/dist/adapters/index.d.ts.map +0 -1
  398. package/dist/adapters/index.js +0 -2
  399. package/dist/adapters/logger.d.ts +0 -9
  400. package/dist/adapters/logger.d.ts.map +0 -1
  401. package/dist/adapters/logger.js +0 -3
  402. package/dist/adapters/memQueue.d.ts +0 -13
  403. package/dist/adapters/memQueue.d.ts.map +0 -1
  404. package/dist/adapters/memQueue.js +0 -20
  405. package/dist/adapters/mongo-client.d.ts +0 -10
  406. package/dist/adapters/mongo-client.d.ts.map +0 -1
  407. package/dist/adapters/mongo-client.js +0 -13
  408. package/dist/adapters/redis-client.d.ts +0 -39
  409. package/dist/adapters/redis-client.d.ts.map +0 -1
  410. package/dist/adapters/redis-client.js +0 -94
  411. package/dist/api/ContextProvider.d.ts +0 -31
  412. package/dist/api/ContextProvider.d.ts.map +0 -1
  413. package/dist/api/ContextProvider.js +0 -38
  414. package/dist/api/codec.d.ts +0 -5
  415. package/dist/api/codec.d.ts.map +0 -1
  416. package/dist/api/codec.js +0 -5
  417. package/dist/api/internal/RequestContextMiddleware.d.ts +0 -5
  418. package/dist/api/internal/RequestContextMiddleware.d.ts.map +0 -1
  419. package/dist/api/internal/RequestContextMiddleware.js +0 -35
  420. package/dist/api/internal/auth.d.ts +0 -15
  421. package/dist/api/internal/auth.d.ts.map +0 -1
  422. package/dist/api/internal/auth.js +0 -47
  423. package/dist/api/internal/events.d.ts +0 -9
  424. package/dist/api/internal/events.d.ts.map +0 -1
  425. package/dist/api/internal/events.js +0 -42
  426. package/dist/api/internal/health.d.ts +0 -3
  427. package/dist/api/internal/health.d.ts.map +0 -1
  428. package/dist/api/internal/health.js +0 -5
  429. package/dist/api/layerUtils.d.ts +0 -24
  430. package/dist/api/layerUtils.d.ts.map +0 -1
  431. package/dist/api/layerUtils.js +0 -16
  432. package/dist/api/middlewares.d.ts +0 -10
  433. package/dist/api/middlewares.d.ts.map +0 -1
  434. package/dist/api/reportError.d.ts +0 -4
  435. package/dist/api/reportError.d.ts.map +0 -1
  436. package/dist/api/reportError.js +0 -27
  437. package/dist/api/routing/middleware/RouterMiddleware.d.ts +0 -15
  438. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +0 -1
  439. package/dist/api/routing/middleware/middleware.d.ts +0 -9
  440. package/dist/api/routing/middleware/middleware.d.ts.map +0 -1
  441. package/dist/api/routing/middleware/middleware.js +0 -92
  442. package/dist/api/routing/middleware.d.ts +0 -4
  443. package/dist/api/routing/middleware.d.ts.map +0 -1
  444. package/dist/api/routing/schema/jwt.d.ts +0 -4
  445. package/dist/api/routing/schema/jwt.d.ts.map +0 -1
  446. package/dist/api/routing/schema/jwt.js +0 -12
  447. package/dist/api/routing/tsort.d.ts +0 -8
  448. package/dist/api/routing/tsort.d.ts.map +0 -1
  449. package/dist/api/routing/tsort.js +0 -51
  450. package/dist/api/routing/utils.d.ts +0 -19
  451. package/dist/api/routing/utils.d.ts.map +0 -1
  452. package/dist/api/routing/utils.js +0 -44
  453. package/dist/api/routing.d.ts +0 -138
  454. package/dist/api/routing.d.ts.map +0 -1
  455. package/dist/api/routing.js +0 -166
  456. package/dist/api/setupRequest.d.ts +0 -12
  457. package/dist/api/setupRequest.d.ts.map +0 -1
  458. package/dist/api/setupRequest.js +0 -44
  459. package/dist/api/util.d.ts +0 -3
  460. package/dist/api/util.d.ts.map +0 -1
  461. package/dist/api/util.js +0 -14
  462. package/eslint.config.mjs +0 -24
  463. package/src/Emailer/service.ts +0 -52
  464. package/src/Emailer.ts +0 -1
  465. package/src/Model/Repository/ext.ts +0 -283
  466. package/src/Model/Repository/internal/internal.ts +0 -577
  467. package/src/Model/Repository/legacy.ts +0 -27
  468. package/src/Model/Repository/makeRepo.ts +0 -139
  469. package/src/Model/Repository/service.ts +0 -627
  470. package/src/Model/Repository/validation.ts +0 -31
  471. package/src/Model/Repository.ts +0 -5
  472. package/src/Model/dsl.ts +0 -128
  473. package/src/Model/filter/filterApi.ts +0 -60
  474. package/src/Model/filter/types/errors.ts +0 -47
  475. package/src/Model/filter/types/fields.ts +0 -50
  476. package/src/Model/filter/types/path/common.ts +0 -404
  477. package/src/Model/filter/types/path/eager.ts +0 -298
  478. package/src/Model/filter/types/path/index.ts +0 -4
  479. package/src/Model/filter/types/utils.ts +0 -128
  480. package/src/Model/filter/types/validator.ts +0 -46
  481. package/src/Model/filter/types.ts +0 -6
  482. package/src/Model/query/dsl.ts +0 -2110
  483. package/src/Model/query/new-kid-interpreter.ts +0 -210
  484. package/src/Model/query.ts +0 -13
  485. package/src/Model.ts +0 -3
  486. package/src/Operations.ts +0 -235
  487. package/src/OperationsRepo.ts +0 -16
  488. package/src/QueueMaker/service.ts +0 -17
  489. package/src/RequestContext.ts +0 -63
  490. package/src/Store/ContextMapContainer.ts +0 -20
  491. package/src/Store/service.ts +0 -184
  492. package/src/Store.ts +0 -1
  493. package/src/adapters/ServiceBus.ts +0 -209
  494. package/src/adapters/index.ts +0 -0
  495. package/src/adapters/logger.ts +0 -3
  496. package/src/api/internal/auth.ts +0 -68
  497. package/src/api/routing/middleware.ts +0 -6
  498. package/src/api/routing.ts +0 -598
  499. package/src/api/setupRequest.ts +0 -84
  500. /package/src/{adapters/SQL.ts → SQL.ts} +0 -0
  501. /package/src/{api/codec.ts → codec.ts} +0 -0
  502. /package/src/{api/internal → internal}/health.ts +0 -0
  503. /package/src/{api/middlewares.ts → middlewares.ts} +0 -0
  504. /package/src/{api/routing → routing}/tsort.ts +0 -0
  505. /package/src/{api/util.ts → util.ts} +0 -0
@@ -0,0 +1,735 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
3
+ import type { NonEmptyReadonlyArray } from "effect-app/Array"
4
+ import { toNonEmptyArray } from "effect-app/Array"
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 * as Context from "effect/Context"
11
+ import * as Layer from "effect/Layer"
12
+ import * as LayerMap from "effect/LayerMap"
13
+ import * as Struct from "effect/Struct"
14
+ import { SqlClient } from "effect/unstable/sql"
15
+ import { OptimisticConcurrencyException } from "../errors.js"
16
+ import { InfraLogger } from "../logger.js"
17
+ import { annotateDb, type DbSystem } from "../otel.js"
18
+ import { buildWhereSQLQuery, logQuery, type SQLDialect, sqliteDialect } from "./SQL/query.js"
19
+ import { makeETag } from "./utils.js"
20
+
21
+ export type WithNsTransactionFn = <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>
22
+
23
+ export class WithNsTransaction
24
+ extends Context.Service<WithNsTransaction, WithNsTransactionFn>()("effect-app/WithNsTransaction")
25
+ {}
26
+
27
+ /** @internal */
28
+ export const parseRow = <Encoded extends FieldValues>(
29
+ row: { id: string; _etag: string | null; data: string },
30
+ idKey: PropertyKey,
31
+ defaultValues: Partial<Encoded>
32
+ ): PersistenceModelType<Encoded> => {
33
+ const data = (typeof row.data === "string" ? JSON.parse(row.data) : row.data) as object
34
+ return { ...defaultValues, ...data, [idKey]: row.id, _etag: row._etag ?? undefined } as PersistenceModelType<Encoded>
35
+ }
36
+
37
+ const parseSelectRow = (
38
+ row: Record<string, unknown>,
39
+ idKey: PropertyKey
40
+ ): any => {
41
+ const result: Record<string, unknown> = {}
42
+ for (const [key, value] of Object.entries(row)) {
43
+ if (key === "id") {
44
+ result[idKey as string] = value
45
+ result["id"] = value
46
+ } else if (typeof value === "string") {
47
+ try {
48
+ result[key] = JSON.parse(value)
49
+ } catch {
50
+ result[key] = value
51
+ }
52
+ } else {
53
+ result[key] = value
54
+ }
55
+ }
56
+ return result
57
+ }
58
+
59
+ function makeSQLStoreInt(system: DbSystem, dialect: SQLDialect, jsonColumnType: string) {
60
+ return Effect.fnUntraced(function*({ prefix }: StorageConfig) {
61
+ const sql = yield* SqlClient.SqlClient
62
+ return {
63
+ make: Effect.fnUntraced(function*<IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>(
64
+ name: string,
65
+ idKey: IdKey,
66
+ seed?: Effect.Effect<Iterable<Encoded>, E, R>,
67
+ config?: StoreConfig<Encoded>
68
+ ) {
69
+ type PM = PersistenceModelType<Encoded>
70
+ const tableName = `${prefix}${name}`
71
+ const defaultValues = config?.defaultValues ?? {}
72
+
73
+ const resolveNamespace = !config?.allowNamespace
74
+ ? Effect.succeed("primary")
75
+ : storeId.pipe(Effect.map((namespace) => {
76
+ if (namespace !== "primary" && !config.allowNamespace!(namespace)) {
77
+ throw new Error(`Namespace ${namespace} not allowed!`)
78
+ }
79
+ return namespace
80
+ }))
81
+
82
+ const ensureTable = sql
83
+ .unsafe(
84
+ `CREATE TABLE IF NOT EXISTS "${tableName}" (id TEXT NOT NULL, _namespace TEXT NOT NULL DEFAULT 'primary', _etag TEXT, data ${jsonColumnType} NOT NULL, PRIMARY KEY (id, _namespace))`
85
+ )
86
+ .pipe(
87
+ Effect.andThen(
88
+ sql.unsafe(
89
+ `CREATE TABLE IF NOT EXISTS "_migrations" (id TEXT NOT NULL, version TEXT NOT NULL, PRIMARY KEY (id, version))`
90
+ )
91
+ ),
92
+ Effect.orDie,
93
+ Effect.asVoid
94
+ )
95
+
96
+ const toRow = (e: PM) => {
97
+ const newE = makeETag(e)
98
+ const id = newE[idKey] as string
99
+ const { _etag, [idKey]: _id, ...rest } = newE as any
100
+ const data = JSON.stringify(rest)
101
+ return { id, _etag: newE._etag!, data, item: newE }
102
+ }
103
+
104
+ const exec = (query: string, params?: readonly unknown[]) => sql.unsafe(query, params as any).pipe(Effect.orDie)
105
+
106
+ const setInternal = Effect.fnUntraced(function*(e: PM, ns: string) {
107
+ const row = toRow(e)
108
+ if (e._etag) {
109
+ yield* exec(
110
+ `UPDATE "${tableName}" SET _etag = ?, data = ? WHERE id = ? AND _etag = ? AND _namespace = ?`,
111
+ [row._etag, row.data, row.id, e._etag, ns]
112
+ )
113
+ const existing = yield* exec(
114
+ `SELECT _etag FROM "${tableName}" WHERE id = ? AND _namespace = ?`,
115
+ [row.id, ns]
116
+ )
117
+ const current = (existing as any[])[0]
118
+ if (!current || current._etag !== row._etag) {
119
+ if (current) {
120
+ return yield* new OptimisticConcurrencyException({
121
+ type: name,
122
+ id: row.id,
123
+ current: current._etag,
124
+ found: e._etag,
125
+ code: 412
126
+ })
127
+ }
128
+ return yield* new OptimisticConcurrencyException({
129
+ type: name,
130
+ id: row.id,
131
+ current: "",
132
+ found: e._etag,
133
+ code: 404
134
+ })
135
+ }
136
+ } else {
137
+ yield* exec(
138
+ `INSERT INTO "${tableName}" (id, _namespace, _etag, data) VALUES (?, ?, ?, ?)`,
139
+ [row.id, ns, row._etag, row.data]
140
+ )
141
+ }
142
+ return row.item
143
+ })
144
+
145
+ const bulkSetInternal = (items: NonEmptyReadonlyArray<PM>, ns: string) =>
146
+ sql
147
+ .withTransaction(Effect.forEach(items, (e) => setInternal(e, ns)))
148
+ .pipe(
149
+ Effect.orDie,
150
+ Effect.map((_) => _ as unknown as NonEmptyReadonlyArray<PM>)
151
+ )
152
+
153
+ const ctx = yield* Effect.context<R>()
154
+ const seedCache = new Map<string, Effect.Effect<void>>()
155
+ const makeSeedEffect = Effect.fnUntraced(function*(ns: string) {
156
+ yield* ensureTable
157
+ if (!seed) return
158
+ const existing = yield* exec(
159
+ `SELECT id FROM "_migrations" WHERE id = ? AND version = ?`,
160
+ [`${tableName}::${ns}`, tableName]
161
+ )
162
+ if ((existing as any[]).length > 0) return
163
+ yield* InfraLogger.logInfo(`Seeding data for ${name} (namespace: ${ns})`)
164
+ const items = yield* seed.pipe(Effect.provide(ctx), Effect.orDie)
165
+ const ne = toNonEmptyArray([...items])
166
+ if (Option.isSome(ne)) yield* bulkSetInternal(ne.value, ns)
167
+ yield* exec(
168
+ `INSERT INTO "_migrations" (id, version) VALUES (?, ?)`,
169
+ [`${tableName}::${ns}`, tableName]
170
+ )
171
+ })
172
+ const seedNamespace = (ns: string) => {
173
+ let cached = seedCache.get(ns)
174
+ if (!cached) {
175
+ cached = Effect.cached(Effect.uninterruptible(makeSeedEffect(ns))).pipe(Effect.runSync)
176
+ seedCache.set(ns, cached)
177
+ }
178
+ return cached
179
+ }
180
+ const s: Store<IdKey, Encoded> = {
181
+ seedNamespace: (ns) => seedNamespace(ns),
182
+
183
+ all: resolveNamespace.pipe(
184
+ Effect.flatMap((ns) => {
185
+ const sqlText = `SELECT id, _etag, data FROM "${tableName}" WHERE _namespace = ?`
186
+ return exec(sqlText, [ns])
187
+ .pipe(
188
+ Effect.map((rows) => (rows as any[]).map((r) => parseRow<Encoded>(r, idKey, defaultValues))),
189
+ annotateDb({
190
+ operation: "all",
191
+ system,
192
+ collection: tableName,
193
+ namespace: ns,
194
+ entity: name,
195
+ query: sqlText
196
+ })
197
+ )
198
+ })
199
+ ),
200
+
201
+ find: (id) =>
202
+ resolveNamespace.pipe(
203
+ Effect.flatMap((ns) => {
204
+ const sqlText = `SELECT id, _etag, data FROM "${tableName}" WHERE id = ? AND _namespace = ?`
205
+ return exec(sqlText, [id, ns])
206
+ .pipe(
207
+ Effect.map((rows) => {
208
+ const row = (rows as any[])[0]
209
+ return row
210
+ ? Option.some(parseRow<Encoded>(row, idKey, defaultValues))
211
+ : Option.none()
212
+ }),
213
+ annotateDb({
214
+ operation: "find",
215
+ system,
216
+ collection: tableName,
217
+ namespace: ns,
218
+ entity: name,
219
+ query: sqlText,
220
+ extra: { "app.entity.id": id }
221
+ })
222
+ )
223
+ })
224
+ ),
225
+
226
+ filter: <U extends keyof Encoded = never>(f: FilterArgs<Encoded, U>) => {
227
+ const filter = f
228
+ .filter
229
+ type M = U extends undefined ? Encoded
230
+ : Pick<Encoded, U>
231
+ return resolveNamespace
232
+ .pipe(Effect
233
+ .flatMap((ns) =>
234
+ Effect
235
+ .sync(() => {
236
+ return buildWhereSQLQuery(
237
+ dialect,
238
+ idKey,
239
+ filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [],
240
+ tableName,
241
+ defaultValues,
242
+ f
243
+ .select as
244
+ | NonEmptyReadonlyArray<
245
+ string | {
246
+ key: string
247
+ subKeys: readonly string[]
248
+ } | {
249
+ key: string
250
+ computed: ComputedProjectionIrExpression
251
+ }
252
+ >
253
+ | undefined,
254
+ f
255
+ .order,
256
+ f
257
+ .skip,
258
+ f
259
+ .limit,
260
+ ns
261
+ )
262
+ })
263
+ .pipe(
264
+ Effect
265
+ .tap((q) => logQuery(q)),
266
+ Effect.tap((q) => Effect.annotateCurrentSpan({ "db.query.text": q.sql })),
267
+ Effect.flatMap((q) =>
268
+ exec(q.sql, q.params).pipe(
269
+ Effect.map((rows) => {
270
+ if (f.select) {
271
+ return (rows as any[]).map((r) => {
272
+ const selected = parseSelectRow(r, idKey)
273
+ return {
274
+ ...Struct.pick(
275
+ defaultValues as any,
276
+ f.select!.filter((_) => typeof _ === "string") as never[]
277
+ ),
278
+ ...selected
279
+ } as M
280
+ })
281
+ }
282
+ return (rows as any[]).map((r) => parseRow<Encoded>(r, idKey, defaultValues) as any as M)
283
+ })
284
+ )
285
+ ),
286
+ annotateDb({
287
+ operation: "filter",
288
+ system,
289
+ collection: tableName,
290
+ namespace: ns,
291
+ entity: name
292
+ })
293
+ )
294
+ ))
295
+ },
296
+
297
+ set: (e) =>
298
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
299
+ setInternal(e, ns).pipe(
300
+ annotateDb({
301
+ operation: "set",
302
+ system,
303
+ collection: tableName,
304
+ namespace: ns,
305
+ entity: name,
306
+ extra: { "app.entity.id": e[idKey] }
307
+ })
308
+ )
309
+ )),
310
+
311
+ batchSet: (items) =>
312
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
313
+ bulkSetInternal(items, ns).pipe(
314
+ annotateDb({
315
+ operation: "batchSet",
316
+ system,
317
+ collection: tableName,
318
+ namespace: ns,
319
+ entity: name
320
+ })
321
+ )
322
+ )),
323
+
324
+ bulkSet: (items) =>
325
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
326
+ bulkSetInternal(items, ns).pipe(
327
+ annotateDb({
328
+ operation: "bulkSet",
329
+ system,
330
+ collection: tableName,
331
+ namespace: ns,
332
+ entity: name
333
+ })
334
+ )
335
+ )),
336
+
337
+ batchRemove: (ids) => {
338
+ const placeholders = ids.map(() => "?").join(", ")
339
+ return resolveNamespace.pipe(Effect.flatMap((ns) => {
340
+ const sqlText = `DELETE FROM "${tableName}" WHERE id IN (${placeholders}) AND _namespace = ?`
341
+ return exec(sqlText, [...ids, ns])
342
+ .pipe(
343
+ Effect.asVoid,
344
+ annotateDb({
345
+ operation: "batchRemove",
346
+ system,
347
+ collection: tableName,
348
+ namespace: ns,
349
+ entity: name,
350
+ query: sqlText
351
+ })
352
+ )
353
+ }))
354
+ },
355
+
356
+ queryRaw: (query) =>
357
+ s.all.pipe(
358
+ Effect.map(query.memory),
359
+ annotateDb({
360
+ operation: "queryRaw",
361
+ system,
362
+ collection: tableName,
363
+ entity: name
364
+ })
365
+ )
366
+ }
367
+
368
+ // Eagerly seed primary namespace on initialization
369
+ yield* seedNamespace("primary")
370
+
371
+ return s
372
+ })
373
+ }
374
+ })
375
+ }
376
+
377
+ type WithNsSqlFn = <A, E2, R2>(
378
+ ns: string,
379
+ f: (sql: SqlClient.SqlClient) => Effect.Effect<A, E2, R2>
380
+ ) => Effect.Effect<A, E2, R2>
381
+
382
+ function makeSQLiteStorePerNs(
383
+ withNsSql: WithNsSqlFn,
384
+ { prefix }: StorageConfig
385
+ ) {
386
+ return {
387
+ make: Effect.fnUntraced(function*<IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>(
388
+ name: string,
389
+ idKey: IdKey,
390
+ seed?: Effect.Effect<Iterable<Encoded>, E, R>,
391
+ config?: StoreConfig<Encoded>
392
+ ) {
393
+ type PM = PersistenceModelType<Encoded>
394
+ const tableName = `${prefix}${name}`
395
+ const defaultValues = config?.defaultValues ?? {}
396
+
397
+ const resolveNamespace = !config?.allowNamespace
398
+ ? Effect.succeed("primary")
399
+ : storeId.pipe(Effect.map((namespace) => {
400
+ if (namespace !== "primary" && !config.allowNamespace!(namespace)) {
401
+ throw new Error(`Namespace ${namespace} not allowed!`)
402
+ }
403
+ return namespace
404
+ }))
405
+
406
+ const toRow = (e: PM) => {
407
+ const newE = makeETag(e)
408
+ const id = newE[idKey] as string
409
+ const { _etag, [idKey]: _id, ...rest } = newE as any
410
+ const data = JSON.stringify(rest)
411
+ return { id, _etag: newE._etag!, data, item: newE }
412
+ }
413
+
414
+ const exec = (ns: string, query: string, params?: readonly unknown[]) =>
415
+ withNsSql(ns, (sql) => sql.unsafe(query, params as any).pipe(Effect.orDie))
416
+
417
+ const ensureTable = (ns: string) =>
418
+ withNsSql(ns, (sql) =>
419
+ sql
420
+ .unsafe(
421
+ `CREATE TABLE IF NOT EXISTS "${tableName}" (id TEXT NOT NULL PRIMARY KEY, _etag TEXT, data JSON NOT NULL)`
422
+ )
423
+ .pipe(
424
+ Effect.andThen(
425
+ sql.unsafe(
426
+ `CREATE TABLE IF NOT EXISTS "_migrations" (id TEXT NOT NULL, version TEXT NOT NULL, PRIMARY KEY (id, version))`
427
+ )
428
+ ),
429
+ Effect.orDie,
430
+ Effect.asVoid
431
+ ))
432
+
433
+ const setInternal = Effect.fnUntraced(function*(e: PM, ns: string) {
434
+ const row = toRow(e)
435
+ if (e._etag) {
436
+ yield* exec(
437
+ ns,
438
+ `UPDATE "${tableName}" SET _etag = ?, data = ? WHERE id = ? AND _etag = ?`,
439
+ [row._etag, row.data, row.id, e._etag]
440
+ )
441
+ const existing = yield* exec(
442
+ ns,
443
+ `SELECT _etag FROM "${tableName}" WHERE id = ?`,
444
+ [row.id]
445
+ )
446
+ const current = (existing as any[])[0]
447
+ if (!current || current._etag !== row._etag) {
448
+ if (current) {
449
+ return yield* new OptimisticConcurrencyException({
450
+ type: name,
451
+ id: row.id,
452
+ current: current._etag,
453
+ found: e._etag,
454
+ code: 412
455
+ })
456
+ }
457
+ return yield* new OptimisticConcurrencyException({
458
+ type: name,
459
+ id: row.id,
460
+ current: "",
461
+ found: e._etag,
462
+ code: 404
463
+ })
464
+ }
465
+ } else {
466
+ yield* exec(
467
+ ns,
468
+ `INSERT INTO "${tableName}" (id, _etag, data) VALUES (?, ?, ?)`,
469
+ [row.id, row._etag, row.data]
470
+ )
471
+ }
472
+ return row.item
473
+ })
474
+
475
+ const bulkSetInternal = (items: NonEmptyReadonlyArray<PM>, ns: string) =>
476
+ withNsSql(ns, (sql) =>
477
+ sql
478
+ .withTransaction(Effect.forEach(items, (e) => setInternal(e, ns)))
479
+ .pipe(
480
+ Effect.orDie,
481
+ Effect.map((_) => _ as unknown as NonEmptyReadonlyArray<PM>)
482
+ ))
483
+
484
+ const ctx = yield* Effect.context<R>()
485
+ const seedCache = new Map<string, Effect.Effect<void>>()
486
+ const makeSeedEffect = Effect.fnUntraced(function*(ns: string) {
487
+ yield* ensureTable(ns)
488
+ if (!seed) return
489
+ const existing = yield* exec(
490
+ ns,
491
+ `SELECT id FROM "_migrations" WHERE id = ? AND version = ?`,
492
+ [tableName, tableName]
493
+ )
494
+ if ((existing as any[]).length > 0) return
495
+ yield* InfraLogger.logInfo(`Seeding data for ${name} (namespace: ${ns})`)
496
+ const items = yield* seed.pipe(Effect.provide(ctx), Effect.orDie)
497
+ const ne = toNonEmptyArray([...items])
498
+ if (Option.isSome(ne)) yield* bulkSetInternal(ne.value, ns)
499
+ yield* exec(
500
+ ns,
501
+ `INSERT INTO "_migrations" (id, version) VALUES (?, ?)`,
502
+ [tableName, tableName]
503
+ )
504
+ })
505
+ const seedNamespace = (ns: string) => {
506
+ let cached = seedCache.get(ns)
507
+ if (!cached) {
508
+ cached = Effect.cached(Effect.uninterruptible(makeSeedEffect(ns))).pipe(Effect.runSync)
509
+ seedCache.set(ns, cached)
510
+ }
511
+ return cached
512
+ }
513
+
514
+ const s: Store<IdKey, Encoded> = {
515
+ seedNamespace: (ns) => seedNamespace(ns),
516
+
517
+ all: resolveNamespace.pipe(Effect.flatMap((ns) => {
518
+ const sqlText = `SELECT id, _etag, data FROM "${tableName}"`
519
+ return exec(ns, sqlText)
520
+ .pipe(
521
+ Effect.map((rows) => (rows as any[]).map((r) => parseRow<Encoded>(r, idKey, defaultValues))),
522
+ annotateDb({
523
+ operation: "all",
524
+ system: "sqlite",
525
+ collection: tableName,
526
+ namespace: ns,
527
+ entity: name,
528
+ query: sqlText
529
+ })
530
+ )
531
+ })),
532
+
533
+ find: (id) =>
534
+ resolveNamespace.pipe(
535
+ Effect.flatMap((ns) => {
536
+ const sqlText = `SELECT id, _etag, data FROM "${tableName}" WHERE id = ?`
537
+ return exec(ns, sqlText, [id])
538
+ .pipe(
539
+ Effect.map((rows) => {
540
+ const row = (rows as any[])[0]
541
+ return row
542
+ ? Option.some(parseRow<Encoded>(row, idKey, defaultValues))
543
+ : Option.none()
544
+ }),
545
+ annotateDb({
546
+ operation: "find",
547
+ system: "sqlite",
548
+ collection: tableName,
549
+ namespace: ns,
550
+ entity: name,
551
+ query: sqlText,
552
+ extra: { "app.entity.id": id }
553
+ })
554
+ )
555
+ })
556
+ ),
557
+
558
+ filter: <U extends keyof Encoded = never>(f: FilterArgs<Encoded, U>) => {
559
+ const filter = f
560
+ .filter
561
+ type M = U extends undefined ? Encoded
562
+ : Pick<Encoded, U>
563
+ return resolveNamespace
564
+ .pipe(Effect
565
+ .flatMap((ns) =>
566
+ Effect
567
+ .sync(() =>
568
+ buildWhereSQLQuery(
569
+ sqliteDialect,
570
+ idKey,
571
+ filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [],
572
+ tableName,
573
+ defaultValues,
574
+ f
575
+ .select as
576
+ | NonEmptyReadonlyArray<
577
+ string | {
578
+ key: string
579
+ subKeys: readonly string[]
580
+ } | {
581
+ key: string
582
+ computed: ComputedProjectionIrExpression
583
+ }
584
+ >
585
+ | undefined,
586
+ f
587
+ .order as NonEmptyReadonlyArray<{ key: string; direction: "ASC" | "DESC" }> | undefined,
588
+ f
589
+ .skip,
590
+ f
591
+ .limit
592
+ )
593
+ )
594
+ .pipe(
595
+ Effect
596
+ .tap((q) => logQuery(q)),
597
+ Effect.tap((q) => Effect.annotateCurrentSpan({ "db.query.text": q.sql })),
598
+ Effect.flatMap((q) =>
599
+ exec(ns, q.sql, q.params).pipe(
600
+ Effect.map((rows) => {
601
+ if (f.select) {
602
+ return (rows as any[]).map((r) => {
603
+ const selected = parseSelectRow(r, idKey)
604
+ return {
605
+ ...Struct.pick(
606
+ defaultValues as any,
607
+ f.select!.filter((_) => typeof _ === "string") as never[]
608
+ ),
609
+ ...selected
610
+ } as M
611
+ })
612
+ }
613
+ return (rows as any[]).map((r) => parseRow<Encoded>(r, idKey, defaultValues) as any as M)
614
+ })
615
+ )
616
+ ),
617
+ annotateDb({
618
+ operation: "filter",
619
+ system: "sqlite",
620
+ collection: tableName,
621
+ namespace: ns,
622
+ entity: name
623
+ })
624
+ )
625
+ ))
626
+ },
627
+
628
+ set: (e) =>
629
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
630
+ setInternal(e, ns).pipe(
631
+ annotateDb({
632
+ operation: "set",
633
+ system: "sqlite",
634
+ collection: tableName,
635
+ namespace: ns,
636
+ entity: name,
637
+ extra: { "app.entity.id": e[idKey] }
638
+ })
639
+ )
640
+ )),
641
+
642
+ batchSet: (items) =>
643
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
644
+ bulkSetInternal(items, ns).pipe(
645
+ annotateDb({
646
+ operation: "batchSet",
647
+ system: "sqlite",
648
+ collection: tableName,
649
+ namespace: ns,
650
+ entity: name
651
+ })
652
+ )
653
+ )),
654
+
655
+ bulkSet: (items) =>
656
+ resolveNamespace.pipe(Effect.flatMap((ns) =>
657
+ bulkSetInternal(items, ns).pipe(
658
+ annotateDb({
659
+ operation: "bulkSet",
660
+ system: "sqlite",
661
+ collection: tableName,
662
+ namespace: ns,
663
+ entity: name
664
+ })
665
+ )
666
+ )),
667
+
668
+ batchRemove: (ids) => {
669
+ const placeholders = ids.map(() => "?").join(", ")
670
+ return resolveNamespace.pipe(Effect.flatMap((ns) => {
671
+ const sqlText = `DELETE FROM "${tableName}" WHERE id IN (${placeholders})`
672
+ return exec(ns, sqlText, [...ids])
673
+ .pipe(
674
+ Effect.asVoid,
675
+ annotateDb({
676
+ operation: "batchRemove",
677
+ system: "sqlite",
678
+ collection: tableName,
679
+ namespace: ns,
680
+ entity: name,
681
+ query: sqlText
682
+ })
683
+ )
684
+ }))
685
+ },
686
+
687
+ queryRaw: (query) =>
688
+ s.all.pipe(
689
+ Effect.map(query.memory),
690
+ annotateDb({
691
+ operation: "queryRaw",
692
+ system: "sqlite",
693
+ collection: tableName,
694
+ entity: name
695
+ })
696
+ )
697
+ }
698
+
699
+ yield* seedNamespace("primary")
700
+
701
+ return s
702
+ })
703
+ }
704
+ }
705
+
706
+ export function SQLiteStoreLayer(
707
+ cfg: StorageConfig,
708
+ options?: { makeSqlClientLayer?: (namespace: string) => Layer.Layer<SqlClient.SqlClient> }
709
+ ) {
710
+ if (options?.makeSqlClientLayer) {
711
+ return Layer.effectContext(
712
+ Effect.gen(function*() {
713
+ const layerMap = yield* LayerMap.make(
714
+ (namespace: string) => options.makeSqlClientLayer!(namespace),
715
+ { idleTimeToLive: "10 minutes" }
716
+ )
717
+
718
+ const withNsSql: WithNsSqlFn = (ns, f) => SqlClient.SqlClient.use(f).pipe(Effect.provide(layerMap.get(ns)))
719
+
720
+ const storeMaker = makeSQLiteStorePerNs(withNsSql, cfg)
721
+
722
+ const withTransaction: WithNsTransactionFn = (effect) =>
723
+ storeId.pipe(
724
+ Effect.flatMap((ns) => withNsSql(ns, (sql) => sql.withTransaction(effect).pipe(Effect.orDie)))
725
+ )
726
+
727
+ return StoreMaker.context(storeMaker).pipe(
728
+ Context.add(WithNsTransaction, withTransaction)
729
+ )
730
+ })
731
+ )
732
+ }
733
+ return StoreMaker
734
+ .toLayer(makeSQLStoreInt("sqlite", sqliteDialect, "JSON")(cfg))
735
+ }