@effect-app/infra 4.0.0-beta.3 → 4.0.0-beta.300

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