@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
@@ -1,11 +1,25 @@
1
+ import { SqliteClient } from "@effect/sql-sqlite-node"
1
2
  import { describe, expect, it } from "@effect/vitest"
2
- import { Array, Config, Effect, flow, Layer, ManagedRuntime, Redacted, References, Result, S, ServiceMap } from "effect-app"
3
+ import * as Array from "effect-app/Array"
4
+ import * as Config from "effect-app/Config"
5
+ import * as Context from "effect-app/Context"
6
+ import * as Effect from "effect-app/Effect"
7
+ import * as Layer from "effect-app/Layer"
8
+ import { and, computed, or, project, projectComputed, relation, where, whereEvery, whereSome } from "effect-app/Model/query"
9
+ import { makeRepo } from "effect-app/Model/Repository/makeRepo"
10
+ import { RepositoryRegistryLive } from "effect-app/Model/Repository/Registry"
11
+ import * as S from "effect-app/Schema"
12
+ import { setupRequestContextFromCurrent } from "effect-app/setupRequest"
3
13
  import { LogLevels } from "effect-app/utils"
4
- import { setupRequestContextFromCurrent } from "../src/api/setupRequest.js"
5
- import { and, or, project, where, whereEvery, whereSome } from "../src/Model/query.js"
6
- import { makeRepo } from "../src/Model/Repository/makeRepo.js"
14
+ import { flow } from "effect/Function"
15
+ import * as ManagedRuntime from "effect/ManagedRuntime"
16
+ import * as Redacted from "effect/Redacted"
17
+ import * as References from "effect/References"
18
+ import * as Result from "effect/Result"
19
+ import * as Struct from "effect/Struct"
7
20
  import { CosmosStoreLayer } from "../src/Store/Cosmos.js"
8
21
  import { MemoryStoreLive } from "../src/Store/Memory.js"
22
+ import { SQLiteStoreLayer } from "../src/Store/SQL.js"
9
23
 
10
24
  export const rt = ManagedRuntime.make(Layer.mergeAll(
11
25
  Layer.effect(
@@ -24,7 +38,7 @@ class Something extends S.Class<Something>("Something")({
24
38
  id: S.String,
25
39
  name: S.String,
26
40
  description: S.String,
27
- items: S.Array(S.Struct({ id: S.String, value: S.Number, description: S.String }))
41
+ items: S.Array(S.Struct({ id: S.String, value: S.Finite, description: S.String }))
28
42
  }) {}
29
43
 
30
44
  const items = [
@@ -49,7 +63,7 @@ const items = [
49
63
  ]
50
64
 
51
65
  // @effect-diagnostics-next-line missingEffectServiceDependency:off
52
- class SomethingRepo extends ServiceMap.Service<SomethingRepo>()(
66
+ class SomethingRepo extends Context.Service<SomethingRepo>()(
53
67
  "SomethingRepo",
54
68
  {
55
69
  make: Effect.gen(function*() {
@@ -76,28 +90,31 @@ class SomethingRepo extends ServiceMap.Service<SomethingRepo>()(
76
90
  static readonly Test = this
77
91
  .layer
78
92
  .pipe(
79
- Layer.provide(MemoryStoreLive)
93
+ Layer.provide(Layer.merge(MemoryStoreLive, RepositoryRegistryLive))
80
94
  )
81
95
 
82
96
  static readonly TestCosmos = this
83
97
  .layer
84
98
  .pipe(
85
99
  Layer.provide(
86
- Effect.gen(function*() {
87
- const url = yield* Config.redacted("STORAGE_URL").pipe(
88
- Config.withDefault(
89
- Redacted.make(
90
- // the emulator doesn't implement array projections :/ so you need an actual cloud instance!
91
- "AccountEndpoint=http://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
100
+ Effect
101
+ .gen(function*() {
102
+ const url = yield* Config.redacted("STORAGE_URL").pipe(
103
+ Config.withDefault(
104
+ Redacted.make(
105
+ // the emulator doesn't implement array projections :/ so you need an actual cloud instance!
106
+ "AccountEndpoint=http://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="
107
+ )
92
108
  )
93
109
  )
94
- )
95
- return CosmosStoreLayer({
96
- dbName: "test",
97
- prefix: "",
98
- url
110
+ return CosmosStoreLayer({
111
+ dbName: "test",
112
+ prefix: "",
113
+ url
114
+ })
115
+ .pipe(Layer.merge(RepositoryRegistryLive))
99
116
  })
100
- }).pipe(Layer.unwrap)
117
+ .pipe(Layer.unwrap)
101
118
  )
102
119
  )
103
120
  }
@@ -107,7 +124,7 @@ describe("select first-level array fields", () => {
107
124
  .gen(function*() {
108
125
  const repo = yield* SomethingRepo
109
126
 
110
- const projected = S.Struct({ name: S.String, items: S.Array(S.Struct({ id: S.String, value: S.Number })) })
127
+ const projected = S.Struct({ name: S.String, items: S.Array(S.Struct({ id: S.String, value: S.Finite })) })
111
128
 
112
129
  // ok crazy lol, "value" is a reserved word in CosmosDB, so we have to use t["value"] as a field name instead of t.value
113
130
  const items = yield* repo.queryRaw(projected, {
@@ -159,7 +176,7 @@ describe("select first-level array fields", () => {
159
176
  .pipe(Effect.provide(SomethingRepo.Test), rt.runPromise))
160
177
  })
161
178
 
162
- const projected = S.Struct({ name: S.String, items: S.Array(S.Struct({ id: S.String, value: S.Number })) })
179
+ const projected = S.Struct({ name: S.String, items: S.Array(S.Struct({ id: S.String, value: S.Finite })) })
163
180
 
164
181
  const expected = [
165
182
  {
@@ -352,6 +369,67 @@ describe("multi-level", () => {
352
369
  .pipe(Effect.provide(SomethingRepo.Test), rt.runPromise))
353
370
  })
354
371
 
372
+ describe("array length projection", () => {
373
+ const test = Effect
374
+ .gen(function*() {
375
+ const repo = yield* SomethingRepo
376
+ const result = yield* repo.query(
377
+ projectComputed(
378
+ S.Struct({ id: S.String, itemCount: S.NonNegativeInt }),
379
+ computed({ itemCount: relation<S.Codec.Encoded<typeof Something>>("items").length() })
380
+ )
381
+ )
382
+ expect(result).toStrictEqual([
383
+ { id: "1", itemCount: 2 },
384
+ { id: "2", itemCount: 2 }
385
+ ])
386
+ })
387
+ .pipe(setupRequestContextFromCurrent())
388
+
389
+ it.skipIf(!process.env["STORAGE_URL"])("works well in CosmosDB", () =>
390
+ test
391
+ .pipe(Effect.provide(SomethingRepo.TestCosmos), rt.runPromise))
392
+
393
+ it("works well in Memory", () =>
394
+ test
395
+ .pipe(Effect.provide(SomethingRepo.Test), rt.runPromise))
396
+ })
397
+
398
+ describe("computed projections", () => {
399
+ const test = Effect
400
+ .gen(function*() {
401
+ const repo = yield* SomethingRepo
402
+ const output = S.Struct({
403
+ id: S.String,
404
+ pickedCount: S.NonNegativeInt,
405
+ hasPicked: S.Boolean
406
+ })
407
+ const pickedFilter = where("value", "gt", 20)
408
+ const items = yield* repo.query(
409
+ projectComputed(
410
+ output,
411
+ computed({
412
+ pickedCount: relation<S.Codec.Encoded<typeof Something>>("items").count(pickedFilter),
413
+ hasPicked: relation<S.Codec.Encoded<typeof Something>>("items").any(pickedFilter)
414
+ })
415
+ )
416
+ )
417
+ expect(items).toStrictEqual([
418
+ { id: "1", pickedCount: 0, hasPicked: false },
419
+ { id: "2", pickedCount: 2, hasPicked: true }
420
+ ])
421
+ })
422
+ .pipe(setupRequestContextFromCurrent())
423
+
424
+ it.skipIf(!process.env["STORAGE_URL"])("works well in CosmosDB", () =>
425
+ test
426
+ .pipe(Effect.provide(SomethingRepo.TestCosmos), rt.runPromise))
427
+
428
+ it("works well in Memory", () =>
429
+ test
430
+ .pipe(Effect.provide(SomethingRepo.Test), rt.runPromise))
431
+ })
432
+
355
433
  // FUTURE: we need something like this instead:
356
434
  /*
357
435
  const subQuery = <T extends FieldValues>() => <TKey extends keyof T>(key: TKey, type: "some" | "every" = "some") => make<T[TKey][number]>() // todo: mark that this is sub query on field "items"
@@ -369,6 +447,246 @@ describe("multi-level", () => {
369
447
  ))
370
448
  */
371
449
 
450
+ // Mimic scanner MultiPick/EasyLife AllPickList shape:
451
+ // - parent has tagged-state with `at` timestamp
452
+ // - items is NonEmptyArray with state._tag + articleId/articleGTIN
453
+ // - controller filters `state.at gte X` and `state._tag neq closed`
454
+ // then projectComputed with: count, any(initial/picking/packed),
455
+ // every(picked/packed), collectDistinct(articleId)
456
+ const itemStateSchema = S.Union([
457
+ S.TaggedStruct("initial", { at: S.String }),
458
+ S.TaggedStruct("picking", { at: S.String }),
459
+ S.TaggedStruct("picked", { at: S.String }),
460
+ S.TaggedStruct("packed", { at: S.String })
461
+ ])
462
+
463
+ class ArticleLineItem extends S.Class<ArticleLineItem>("ArticleLineItem")({
464
+ articleId: S.String,
465
+ articleGTIN: S.String,
466
+ state: itemStateSchema
467
+ }) {}
468
+
469
+ const stOrderState = S.Union([
470
+ S.TaggedStruct("initial", { at: S.String }),
471
+ S.TaggedStruct("packed", { at: S.String }),
472
+ S.TaggedStruct("closed", { at: S.String })
473
+ ])
474
+
475
+ class Order extends S.Class<Order>("Order")({
476
+ id: S.String,
477
+ state: stOrderState,
478
+ items: S.NonEmptyArray(ArticleLineItem)
479
+ }) {}
480
+
481
+ const orderItems = [
482
+ new Order({
483
+ id: "o-open-1",
484
+ state: { _tag: "initial", at: "2026-05-08T08:00:00Z" },
485
+ items: [
486
+ new ArticleLineItem({
487
+ articleId: "A1",
488
+ articleGTIN: "G1",
489
+ state: { _tag: "picking", at: "2026-05-08T08:01:00Z" }
490
+ }),
491
+ new ArticleLineItem({
492
+ articleId: "A1",
493
+ articleGTIN: "G1",
494
+ state: { _tag: "picked", at: "2026-05-08T08:02:00Z" }
495
+ }),
496
+ new ArticleLineItem({
497
+ articleId: "A2",
498
+ articleGTIN: "G2",
499
+ state: { _tag: "initial", at: "2026-05-08T08:00:00Z" }
500
+ })
501
+ ]
502
+ }),
503
+ new Order({
504
+ id: "o-allpicked-2",
505
+ state: { _tag: "packed", at: "2026-05-07T10:00:00Z" },
506
+ items: [
507
+ new ArticleLineItem({
508
+ articleId: "B1",
509
+ articleGTIN: "GB1",
510
+ state: { _tag: "picked", at: "2026-05-07T09:50:00Z" }
511
+ }),
512
+ new ArticleLineItem({
513
+ articleId: "B2",
514
+ articleGTIN: "GB2",
515
+ state: { _tag: "picked", at: "2026-05-07T09:55:00Z" }
516
+ })
517
+ ]
518
+ }),
519
+ new Order({
520
+ id: "o-closed-3",
521
+ state: { _tag: "closed", at: "2026-05-04T10:00:00Z" },
522
+ items: [
523
+ new ArticleLineItem({
524
+ articleId: "C1",
525
+ articleGTIN: "GC1",
526
+ state: { _tag: "packed", at: "2026-05-04T09:00:00Z" }
527
+ })
528
+ ]
529
+ })
530
+ ]
531
+
532
+ // @effect-diagnostics-next-line missingEffectServiceDependency:off
533
+ class OrderRepo extends Context.Service<OrderRepo>()(
534
+ "OrderRepo",
535
+ {
536
+ make: Effect.gen(function*() {
537
+ const partitionKey = "orders-" + new Date().getTime()
538
+ return yield* makeRepo("Order", Order, { config: { partitionValue: () => partitionKey } })
539
+ })
540
+ }
541
+ ) {
542
+ static readonly layer = Layer
543
+ .effect(
544
+ OrderRepo,
545
+ Effect.gen(function*() {
546
+ const partitionKey = "orders-" + new Date().getTime()
547
+ const repo = OrderRepo.of(
548
+ yield* makeRepo("Order", Order, {
549
+ config: { partitionValue: () => partitionKey }
550
+ })
551
+ )
552
+ yield* repo.saveAndPublish(orderItems).pipe(setupRequestContextFromCurrent("init"))
553
+ return repo
554
+ })
555
+ )
556
+ static readonly Test = this
557
+ .layer
558
+ .pipe(Layer.provide(Layer.merge(MemoryStoreLive, RepositoryRegistryLive)))
559
+
560
+ static readonly TestSqlite = this
561
+ .layer
562
+ .pipe(
563
+ Layer.provide(
564
+ Layer.merge(
565
+ SQLiteStoreLayer({
566
+ url: Redacted.make("sqlite://"),
567
+ prefix: "test_",
568
+ dbName: "test"
569
+ }),
570
+ RepositoryRegistryLive
571
+ )
572
+ ),
573
+ Layer.provide(SqliteClient.layer({ filename: ":memory:" }))
574
+ )
575
+ }
576
+
577
+ describe("scanner-style AllPickList computed projections", () => {
578
+ const test = Effect
579
+ .gen(function*() {
580
+ const repo = yield* OrderRepo
581
+ type OrderEnc = S.Codec.Encoded<typeof Order>
582
+
583
+ const projection = S.Struct({
584
+ id: S.String,
585
+ state: stOrderState,
586
+ articleCount: S.NonNegativeInt,
587
+ hasInitialItem: S.Boolean,
588
+ hasPickingItem: S.Boolean,
589
+ hasPackedItem: S.Boolean,
590
+ allItemsPicked: S.Boolean,
591
+ allItemsPacked: S.Boolean,
592
+ articleIds: S.Array(S.String)
593
+ })
594
+
595
+ const result = yield* repo.query(
596
+ where("state.at", "gte", "2026-05-05T00:00:00Z"),
597
+ and("state._tag", "neq", "closed"),
598
+ projectComputed(
599
+ projection,
600
+ computed({
601
+ articleCount: relation<OrderEnc>("items").count(),
602
+ hasInitialItem: relation<OrderEnc>("items").any(where("state._tag", "initial")),
603
+ hasPickingItem: relation<OrderEnc>("items").any(where("state._tag", "picking")),
604
+ hasPackedItem: relation<OrderEnc>("items").any(where("state._tag", "packed")),
605
+ allItemsPicked: relation<OrderEnc>("items").every(where("state._tag", "picked")),
606
+ allItemsPacked: relation<OrderEnc>("items").every(where("state._tag", "packed")),
607
+ articleIds: relation<OrderEnc>("items").collectDistinct("articleId")
608
+ })
609
+ )
610
+ )
611
+
612
+ const byId = Object.fromEntries(result.map((r) => [r.id, r]))
613
+
614
+ expect(Object.keys(byId).sort()).toEqual(["o-allpicked-2", "o-open-1"])
615
+
616
+ const open = byId["o-open-1"]!
617
+ expect(open.articleCount).toBe(3)
618
+ expect(open.hasInitialItem).toBe(true)
619
+ expect(open.hasPickingItem).toBe(true)
620
+ expect(open.hasPackedItem).toBe(false)
621
+ expect(open.allItemsPicked).toBe(false)
622
+ expect(open.allItemsPacked).toBe(false)
623
+ expect([...open.articleIds].sort()).toEqual(["A1", "A2"])
624
+
625
+ const allp = byId["o-allpicked-2"]!
626
+ expect(allp.articleCount).toBe(2)
627
+ expect(allp.hasInitialItem).toBe(false)
628
+ expect(allp.hasPickingItem).toBe(false)
629
+ expect(allp.hasPackedItem).toBe(false)
630
+ expect(allp.allItemsPicked).toBe(true)
631
+ expect(allp.allItemsPacked).toBe(false)
632
+ expect([...allp.articleIds].sort()).toEqual(["B1", "B2"])
633
+ })
634
+ .pipe(setupRequestContextFromCurrent())
635
+
636
+ it("works well in Memory", () => test.pipe(Effect.provide(OrderRepo.Test), rt.runPromise))
637
+
638
+ it("works well in SQLite", () => test.pipe(Effect.provide(OrderRepo.TestSqlite), rt.runPromise))
639
+ })
640
+
641
+ // Same but mimics the FULL controller projection: includes `items` array
642
+ // (NonEmptyArray) alongside the computed scalars. This tests the
643
+ // memory-side select pipeline that combines subKeys (items) with
644
+ // computedKeys in one Project node.
645
+ describe("scanner-style AllPickList — items + computed combined", () => {
646
+ const test = Effect
647
+ .gen(function*() {
648
+ const repo = yield* OrderRepo
649
+ type OrderEnc = S.Codec.Encoded<typeof Order>
650
+
651
+ const projection = S.Struct({
652
+ id: S.String,
653
+ items: S.NonEmptyArray(ArticleLineItem.mapFields(Struct.pick(["articleId", "articleGTIN"]))),
654
+ articleCount: S.NonNegativeInt,
655
+ allItemsPicked: S.Boolean,
656
+ articleIds: S.Array(S.String)
657
+ })
658
+
659
+ const result = yield* repo.query(
660
+ where("state.at", "gte", "2026-05-05T00:00:00Z"),
661
+ and("state._tag", "neq", "closed"),
662
+ projectComputed(
663
+ projection,
664
+ computed({
665
+ articleCount: relation<OrderEnc>("items").count(),
666
+ allItemsPicked: relation<OrderEnc>("items").every(where("state._tag", "picked")),
667
+ articleIds: relation<OrderEnc>("items").collectDistinct("articleId")
668
+ })
669
+ )
670
+ )
671
+
672
+ expect(result.length).toBe(2)
673
+ const byId = Object.fromEntries(result.map((r) => [r.id, r]))
674
+ const open = byId["o-open-1"]!
675
+ expect(open.items.length).toBe(3)
676
+ expect(open.items[0]).toHaveProperty("articleId")
677
+ expect(open.items[0]).toHaveProperty("articleGTIN")
678
+ expect(open.allItemsPicked).toBe(false)
679
+ const allp = byId["o-allpicked-2"]!
680
+ expect(allp.items.length).toBe(2)
681
+ expect(allp.allItemsPicked).toBe(true)
682
+ })
683
+ .pipe(setupRequestContextFromCurrent())
684
+
685
+ it("works well in Memory", () => test.pipe(Effect.provide(OrderRepo.Test), rt.runPromise))
686
+
687
+ it("works well in SQLite", () => test.pipe(Effect.provide(OrderRepo.TestSqlite), rt.runPromise))
688
+ })
689
+
372
690
  describe("removeByIds", () => {
373
691
  const test = Effect
374
692
  .gen(function*() {
@@ -405,7 +723,7 @@ describe("removeByIds", () => {
405
723
 
406
724
  yield* repo.saveAndPublish(items)
407
725
  const itemsAfterSave = yield* repo.all
408
- yield* repo.removeById(...items.slice(0, 2).map((_) => _.id))
726
+ yield* repo.removeById([items[0]!.id, items[1]!.id])
409
727
 
410
728
  const items2 = yield* repo.all
411
729
 
@@ -0,0 +1,178 @@
1
+ import { describe, expect, it } from "@effect/vitest"
2
+ import * as DataDependencies from "effect-app/DataDependencies"
3
+ import * as Effect from "effect-app/Effect"
4
+ import * as Layer from "effect-app/Layer"
5
+ import { Q } from "effect-app/Model"
6
+ import { makeRepo } from "effect-app/Model/Repository"
7
+ import { RepositoryRegistryLive } from "effect-app/Model/Repository/Registry"
8
+ import * as S from "effect-app/Schema"
9
+ import { setupRequestContextFromCurrent } from "effect-app/setupRequest"
10
+ import * as Ref from "effect/Ref"
11
+ import { MemoryStoreLive } from "../src/Store/Memory.js"
12
+
13
+ class BatchItem extends S.Class<BatchItem>("BatchItem")({
14
+ id: S.String,
15
+ label: S.String
16
+ }) {}
17
+
18
+ const TestStoreLive = Layer.merge(MemoryStoreLive, RepositoryRegistryLive)
19
+
20
+ const A = S.TaggedStruct("A", { id: S.String })
21
+ const B = S.TaggedStruct("B", { id: S.String })
22
+ const C = S.TaggedStruct("C", { id: S.String })
23
+
24
+ const union = S.Union([A, B, C])
25
+
26
+ const a = S.Struct({ id: S.String })
27
+
28
+ const nestedSourceItem = S.TaggedStruct("source-item", {
29
+ id: S.StringId,
30
+ label: S.String
31
+ })
32
+ const nestedProjectedItem = S.TaggedStruct("source-item", {
33
+ id: S.StringId
34
+ })
35
+ type NestedProjectedItem = typeof nestedProjectedItem.Type
36
+ const nestedSource = S.Struct({
37
+ id: S.String,
38
+ items: S.NonEmptyArray(nestedSourceItem),
39
+ label: S.String
40
+ })
41
+ const nestedProjection = S.Struct({
42
+ id: S.String,
43
+ items: S.NonEmptyArray(nestedProjectedItem)
44
+ })
45
+
46
+ const nestedProjectedItemsOf = (
47
+ items: readonly [NestedProjectedItem, ...NestedProjectedItem[]]
48
+ ) => items
49
+
50
+ const nestedUnionSourceA = S.TaggedStruct("nested-a", {
51
+ id: S.String,
52
+ items: S.NonEmptyArray(nestedSourceItem),
53
+ label: S.String
54
+ })
55
+ const nestedUnionSourceB = S.TaggedStruct("nested-b", {
56
+ id: S.String,
57
+ items: S.NonEmptyArray(nestedSourceItem),
58
+ count: S.Number
59
+ })
60
+ const nestedUnionSource = S.Union([nestedUnionSourceA, nestedUnionSourceB])
61
+ const nestedUnionProjection = S.Union([
62
+ nestedUnionSourceA.mapFields((fields) => ({
63
+ id: fields.id,
64
+ _tag: fields._tag,
65
+ items: S.NonEmptyArray(nestedProjectedItem)
66
+ })),
67
+ nestedUnionSourceB.mapFields((fields) => ({
68
+ id: fields.id,
69
+ _tag: fields._tag,
70
+ items: S.NonEmptyArray(nestedProjectedItem)
71
+ }))
72
+ ])
73
+
74
+ describe("repository ext save/remove batching", () => {
75
+ it.effect("supports projecting full repository schema", () =>
76
+ Effect
77
+ .gen(function*() {
78
+ const unionRepo = yield* makeRepo("UnionItem", union, {})
79
+ const aRepo = yield* makeRepo("AItem", a, {})
80
+ const ARepo = yield* makeRepo("TaggedAItem", A, {})
81
+
82
+ expect(yield* unionRepo.query(Q.project(union))).toEqual([])
83
+ expect(yield* aRepo.query(Q.project(a))).toEqual([])
84
+ expect(yield* ARepo.query(Q.project(A))).toEqual([])
85
+ })
86
+ .pipe(
87
+ setupRequestContextFromCurrent(),
88
+ Effect.provide(TestStoreLive)
89
+ ))
90
+
91
+ it.effect("supports nested DTO subset projections", () =>
92
+ Effect
93
+ .gen(function*() {
94
+ const repo = yield* makeRepo("NestedProjectionItem", nestedSource, {})
95
+ const unionRepo = yield* makeRepo("NestedUnionProjectionItem", nestedUnionSource, {})
96
+ const result = yield* repo.query(Q.project(nestedProjection, "project"))
97
+ const unionResult = yield* unionRepo.query(Q.project(nestedUnionProjection, "project"))
98
+
99
+ result.forEach((_) => nestedProjectedItemsOf(_.items))
100
+ unionResult.forEach((_) => nestedProjectedItemsOf(_.items))
101
+ expect(result).toEqual([])
102
+ expect(unionResult).toEqual([])
103
+ })
104
+ .pipe(
105
+ setupRequestContextFromCurrent(),
106
+ Effect.provide(TestStoreLive)
107
+ ))
108
+
109
+ it.effect("supports save batching overload", () =>
110
+ Effect
111
+ .gen(function*() {
112
+ const repo = yield* makeRepo("BatchItem", BatchItem, {})
113
+ const items = [
114
+ new BatchItem({ id: "1", label: "one" }),
115
+ new BatchItem({ id: "2", label: "two" }),
116
+ new BatchItem({ id: "3", label: "three" }),
117
+ new BatchItem({ id: "4", label: "four" })
118
+ ] as const
119
+
120
+ yield* repo.save(items, { batch: 2 })
121
+
122
+ const all = yield* repo.all
123
+ expect(all).toHaveLength(4)
124
+ expect(all.map((_) => _.id).toSorted()).toEqual(["1", "2", "3", "4"])
125
+ })
126
+ .pipe(
127
+ setupRequestContextFromCurrent(),
128
+ Effect.provide(TestStoreLive)
129
+ ))
130
+
131
+ it.effect("supports remove batching overload", () =>
132
+ Effect
133
+ .gen(function*() {
134
+ const repo = yield* makeRepo("BatchItem", BatchItem, {})
135
+ const items = [
136
+ new BatchItem({ id: "1", label: "one" }),
137
+ new BatchItem({ id: "2", label: "two" }),
138
+ new BatchItem({ id: "3", label: "three" }),
139
+ new BatchItem({ id: "4", label: "four" })
140
+ ] as const
141
+
142
+ yield* repo.save(items)
143
+ yield* repo.remove([items[0], items[1], items[2]], { batch: true })
144
+
145
+ const all = yield* repo.all
146
+ expect(all).toHaveLength(1)
147
+ expect(all[0]?.id).toBe("4")
148
+ })
149
+ .pipe(
150
+ setupRequestContextFromCurrent(),
151
+ Effect.provide(TestStoreLive)
152
+ ))
153
+
154
+ it.effect("records repository read and write dependencies", () =>
155
+ Effect
156
+ .gen(function*() {
157
+ const readsRef = yield* Ref.make(DataDependencies.empty())
158
+ const writesRef = yield* Ref.make(DataDependencies.empty())
159
+ const recorder = DataDependencies.makeDataDependencyRecorder(readsRef, writesRef)
160
+
161
+ yield* Effect
162
+ .gen(function*() {
163
+ const repo = yield* makeRepo("DependencyItem", BatchItem, {})
164
+ yield* repo.save(new BatchItem({ id: "1", label: "one" }))
165
+ yield* repo.all
166
+ yield* repo.find("1")
167
+ yield* repo.removeById("1")
168
+ })
169
+ .pipe(Effect.provideService(DataDependencies.DataDependencyRecorder, recorder))
170
+
171
+ expect(yield* Ref.get(readsRef)).toEqual(new Set([DataDependencies.repo("DependencyItem")]))
172
+ expect(yield* Ref.get(writesRef)).toEqual(new Set([DataDependencies.repo("DependencyItem")]))
173
+ })
174
+ .pipe(
175
+ setupRequestContextFromCurrent(),
176
+ Effect.provide(TestStoreLive)
177
+ ))
178
+ })
@@ -1,10 +1,14 @@
1
1
  import { describe, expect, expectTypeOf, it } from "@effect/vitest"
2
- import { Effect, Layer, Result, S, ServiceMap } from "effect-app"
3
2
  import { NotLoggedInError, UnauthorizedError } from "effect-app/client"
3
+ import * as Context from "effect-app/Context"
4
+ import * as Effect from "effect-app/Effect"
4
5
  import { HttpHeaders } from "effect-app/http"
6
+ import * as Layer from "effect-app/Layer"
5
7
  import * as RpcX from "effect-app/rpc"
6
8
  import { MiddlewareMaker } from "effect-app/rpc"
9
+ import * as S from "effect-app/Schema"
7
10
  import type { unhandled } from "effect-app/Types"
11
+ import * as Result from "effect/Result"
8
12
  import { Rpc } from "effect/unstable/rpc"
9
13
  import { type SuccessValue } from "effect/unstable/rpc/RpcMiddleware"
10
14
  import { AllowAnonymous, AllowAnonymousLive, RequestContextMap, RequireRoles, RequireRolesLive, Some, SomeElseMiddleware, SomeElseMiddlewareLive, SomeMiddleware, SomeMiddlewareLive, SomeService, Test, TestLive } from "./fixtures.js"
@@ -63,11 +67,12 @@ const testSuite = (_mw: typeof middleware3) =>
63
67
  "works",
64
68
  Effect.fn(function*() {
65
69
  const defaultOpts = {
70
+ client: null as any, // TODO?
66
71
  headers: HttpHeaders.fromRecordUnsafe({}),
67
72
  payload: { _tag: "Test" },
68
73
  clientId: 0,
69
74
  requestId: "test-id" as any,
70
- rpc: { ...TestRpc, annotations: ServiceMap.make(_mw.requestContext, {}) }
75
+ rpc: { ...TestRpc, annotations: Context.make(_mw.requestContext, {}) }
71
76
  }
72
77
  const next = Effect.void as unknown as Effect.Effect<SuccessValue, unhandled, never>
73
78
  const layer = _mw.layer.pipe(
@@ -89,7 +94,7 @@ const testSuite = (_mw: typeof middleware3) =>
89
94
  headers: HttpHeaders.fromRecordUnsafe({ "x-user": "test-user", "x-is-manager": "true" }),
90
95
  rpc: {
91
96
  ...defaultOpts.rpc,
92
- annotations: ServiceMap.make(_mw.requestContext, { requireRoles: ["manager"] })
97
+ annotations: Context.make(_mw.requestContext, { requireRoles: ["manager"] })
93
98
  }
94
99
  })
95
100
  )
@@ -127,7 +132,7 @@ const testSuite = (_mw: typeof middleware3) =>
127
132
  Object.assign({ ...defaultOpts }, {
128
133
  rpc: {
129
134
  ...defaultOpts.rpc,
130
- annotations: ServiceMap.make(_mw.requestContext, { requireRoles: ["manager"] })
135
+ annotations: Context.make(_mw.requestContext, { requireRoles: ["manager"] })
131
136
  }
132
137
  })
133
138
  )
@@ -153,7 +158,7 @@ const testSuite = (_mw: typeof middleware3) =>
153
158
  {
154
159
  rpc: {
155
160
  ...defaultOpts.rpc,
156
- annotations: ServiceMap.make(_mw.requestContext, { requireRoles: ["manager"] })
161
+ annotations: Context.make(_mw.requestContext, { requireRoles: ["manager"] })
157
162
  }
158
163
  }
159
164
  )