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

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 (503) hide show
  1. package/CHANGELOG.md +1966 -0
  2. package/_check.sh +1 -1
  3. package/dist/CUPS.d.ts +30 -11
  4. package/dist/CUPS.d.ts.map +1 -1
  5. package/dist/CUPS.js +35 -14
  6. package/dist/ClusterCosmos.d.ts +64 -0
  7. package/dist/ClusterCosmos.d.ts.map +1 -0
  8. package/dist/ClusterCosmos.js +487 -0
  9. package/dist/ClusterServiceBus.d.ts +67 -0
  10. package/dist/ClusterServiceBus.d.ts.map +1 -0
  11. package/dist/ClusterServiceBus.js +82 -0
  12. package/dist/ContextProvider.d.ts +34 -0
  13. package/dist/ContextProvider.d.ts.map +1 -0
  14. package/dist/ContextProvider.js +40 -0
  15. package/dist/Emailer/Sendgrid.d.ts +111 -147
  16. package/dist/Emailer/Sendgrid.d.ts.map +1 -1
  17. package/dist/Emailer/Sendgrid.js +24 -19
  18. package/dist/Emailer/fake.d.ts +2 -2
  19. package/dist/Emailer/fake.d.ts.map +1 -1
  20. package/dist/Emailer/fake.js +4 -4
  21. package/dist/MainFiberSet.d.ts +12 -9
  22. package/dist/MainFiberSet.d.ts.map +1 -1
  23. package/dist/MainFiberSet.js +10 -6
  24. package/dist/QueueMaker/SQLQueue.d.ts +8 -9
  25. package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
  26. package/dist/QueueMaker/SQLQueue.js +138 -120
  27. package/dist/QueueMaker/errors.d.ts +5 -3
  28. package/dist/QueueMaker/errors.d.ts.map +1 -1
  29. package/dist/QueueMaker/errors.js +4 -2
  30. package/dist/QueueMaker/memQueue.d.ts +10 -6
  31. package/dist/QueueMaker/memQueue.d.ts.map +1 -1
  32. package/dist/QueueMaker/memQueue.js +84 -68
  33. package/dist/QueueMaker/sbqueue.d.ts +9 -5
  34. package/dist/QueueMaker/sbqueue.d.ts.map +1 -1
  35. package/dist/QueueMaker/sbqueue.js +60 -58
  36. package/dist/RequestFiberSet.d.ts +10 -7
  37. package/dist/RequestFiberSet.d.ts.map +1 -1
  38. package/dist/RequestFiberSet.js +13 -8
  39. package/dist/SQL/Model.d.ts +468 -0
  40. package/dist/SQL/Model.d.ts.map +1 -0
  41. package/dist/SQL/Model.js +469 -0
  42. package/dist/SQL.d.ts +2 -0
  43. package/dist/SQL.d.ts.map +1 -0
  44. package/dist/{adapters/SQL.js → SQL.js} +1 -1
  45. package/dist/ServiceBus.d.ts +61 -0
  46. package/dist/ServiceBus.d.ts.map +1 -0
  47. package/dist/ServiceBus.js +108 -0
  48. package/dist/Store/Cosmos/query.d.ts +15 -4
  49. package/dist/Store/Cosmos/query.d.ts.map +1 -1
  50. package/dist/Store/Cosmos/query.js +179 -41
  51. package/dist/Store/Cosmos.d.ts +3 -3
  52. package/dist/Store/Cosmos.d.ts.map +1 -1
  53. package/dist/Store/Cosmos.js +344 -246
  54. package/dist/Store/Disk.d.ts +5 -5
  55. package/dist/Store/Disk.d.ts.map +1 -1
  56. package/dist/Store/Disk.js +78 -38
  57. package/dist/Store/Memory.d.ts +7 -10
  58. package/dist/Store/Memory.d.ts.map +1 -1
  59. package/dist/Store/Memory.js +326 -66
  60. package/dist/Store/SQL/Pg.d.ts +4 -0
  61. package/dist/Store/SQL/Pg.d.ts.map +1 -0
  62. package/dist/Store/SQL/Pg.js +232 -0
  63. package/dist/Store/SQL/query.d.ts +49 -0
  64. package/dist/Store/SQL/query.d.ts.map +1 -0
  65. package/dist/Store/SQL/query.js +527 -0
  66. package/dist/Store/SQL.d.ts +21 -0
  67. package/dist/Store/SQL.d.ts.map +1 -0
  68. package/dist/Store/SQL.js +449 -0
  69. package/dist/Store/codeFilter.d.ts +5 -5
  70. package/dist/Store/codeFilter.d.ts.map +1 -1
  71. package/dist/Store/codeFilter.js +6 -3
  72. package/dist/Store/index.d.ts +7 -5
  73. package/dist/Store/index.d.ts.map +1 -1
  74. package/dist/Store/index.js +18 -5
  75. package/dist/Store/utils.d.ts +4 -3
  76. package/dist/Store/utils.d.ts.map +1 -1
  77. package/dist/Store/utils.js +5 -5
  78. package/dist/WorkflowEngineCosmos.d.ts +29 -0
  79. package/dist/WorkflowEngineCosmos.d.ts.map +1 -0
  80. package/dist/WorkflowEngineCosmos.js +521 -0
  81. package/dist/WorkflowEngineSqlite.d.ts +24 -0
  82. package/dist/WorkflowEngineSqlite.d.ts.map +1 -0
  83. package/dist/WorkflowEngineSqlite.js +550 -0
  84. package/dist/arbs.d.ts +2 -2
  85. package/dist/arbs.d.ts.map +1 -1
  86. package/dist/arbs.js +5 -3
  87. package/dist/codec.d.ts +5 -0
  88. package/dist/codec.d.ts.map +1 -0
  89. package/dist/codec.js +5 -0
  90. package/dist/cosmos-client.d.ts +16 -0
  91. package/dist/cosmos-client.d.ts.map +1 -0
  92. package/dist/cosmos-client.js +11 -0
  93. package/dist/errorReporter.d.ts +7 -5
  94. package/dist/errorReporter.d.ts.map +1 -1
  95. package/dist/errorReporter.js +23 -27
  96. package/dist/errors.d.ts +1 -1
  97. package/dist/fileUtil.d.ts +2 -2
  98. package/dist/fileUtil.d.ts.map +1 -1
  99. package/dist/fileUtil.js +2 -2
  100. package/dist/index.d.ts +3 -2
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +3 -2
  103. package/dist/internal/RequestContextMiddleware.d.ts +5 -0
  104. package/dist/internal/RequestContextMiddleware.d.ts.map +1 -0
  105. package/dist/internal/RequestContextMiddleware.js +45 -0
  106. package/dist/internal/auth.d.ts +53 -0
  107. package/dist/internal/auth.d.ts.map +1 -0
  108. package/dist/internal/auth.js +180 -0
  109. package/dist/internal/events.d.ts +11 -0
  110. package/dist/internal/events.d.ts.map +1 -0
  111. package/dist/internal/events.js +49 -0
  112. package/dist/internal/health.d.ts +3 -0
  113. package/dist/internal/health.d.ts.map +1 -0
  114. package/dist/internal/health.js +5 -0
  115. package/dist/layerUtils.d.ts +32 -0
  116. package/dist/layerUtils.d.ts.map +1 -0
  117. package/dist/layerUtils.js +17 -0
  118. package/dist/logger/jsonLogger.d.ts +2 -2
  119. package/dist/logger/jsonLogger.d.ts.map +1 -1
  120. package/dist/logger/jsonLogger.js +5 -3
  121. package/dist/logger/logFmtLogger.d.ts +2 -2
  122. package/dist/logger/logFmtLogger.d.ts.map +1 -1
  123. package/dist/logger/logFmtLogger.js +3 -3
  124. package/dist/logger/shared.d.ts +3 -3
  125. package/dist/logger/shared.d.ts.map +1 -1
  126. package/dist/logger/shared.js +5 -5
  127. package/dist/logger.d.ts +1 -1
  128. package/dist/logger.d.ts.map +1 -1
  129. package/dist/memQueue.d.ts +15 -0
  130. package/dist/memQueue.d.ts.map +1 -0
  131. package/dist/memQueue.js +21 -0
  132. package/dist/middlewares.d.ts +10 -0
  133. package/dist/middlewares.d.ts.map +1 -0
  134. package/dist/{api/middlewares.js → middlewares.js} +1 -1
  135. package/dist/mongo-client.d.ts +11 -0
  136. package/dist/mongo-client.d.ts.map +1 -0
  137. package/dist/mongo-client.js +15 -0
  138. package/dist/otel.d.ts +75 -0
  139. package/dist/otel.d.ts.map +1 -0
  140. package/dist/otel.js +65 -0
  141. package/dist/rateLimit.d.ts +12 -4
  142. package/dist/rateLimit.d.ts.map +1 -1
  143. package/dist/rateLimit.js +7 -12
  144. package/dist/redis-client.d.ts +42 -0
  145. package/dist/redis-client.d.ts.map +1 -0
  146. package/dist/redis-client.js +98 -0
  147. package/dist/reportError.d.ts +4 -0
  148. package/dist/reportError.d.ts.map +1 -0
  149. package/dist/reportError.js +28 -0
  150. package/dist/routing/middleware/RouterMiddleware.d.ts +16 -0
  151. package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
  152. package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
  153. package/dist/routing/middleware/middleware.d.ts +48 -0
  154. package/dist/routing/middleware/middleware.d.ts.map +1 -0
  155. package/dist/routing/middleware/middleware.js +128 -0
  156. package/dist/routing/middleware.d.ts +3 -0
  157. package/dist/routing/middleware.d.ts.map +1 -0
  158. package/dist/{api/routing → routing}/middleware.js +1 -2
  159. package/dist/routing/schema/jwt.d.ts +4 -0
  160. package/dist/routing/schema/jwt.d.ts.map +1 -0
  161. package/dist/routing/schema/jwt.js +13 -0
  162. package/dist/routing/tsort.d.ts +8 -0
  163. package/dist/routing/tsort.d.ts.map +1 -0
  164. package/dist/routing/tsort.js +51 -0
  165. package/dist/routing/utils.d.ts +19 -0
  166. package/dist/routing/utils.d.ts.map +1 -0
  167. package/dist/routing/utils.js +45 -0
  168. package/dist/routing.d.ts +184 -0
  169. package/dist/routing.d.ts.map +1 -0
  170. package/dist/routing.js +236 -0
  171. package/dist/test.d.ts +3 -3
  172. package/dist/test.d.ts.map +1 -1
  173. package/dist/test.js +2 -2
  174. package/dist/util.d.ts +3 -0
  175. package/dist/util.d.ts.map +1 -0
  176. package/dist/util.js +14 -0
  177. package/dist/vitest.d.ts +1 -1
  178. package/docs/cluster-storage.md +26 -0
  179. package/docs/workflow-engine.md +262 -0
  180. package/examples/query.ts +47 -39
  181. package/package.json +31 -345
  182. package/run.sh +1 -0
  183. package/src/CUPS.ts +52 -13
  184. package/src/ClusterCosmos.ts +954 -0
  185. package/src/ClusterServiceBus.ts +242 -0
  186. package/src/{api/ContextProvider.ts → ContextProvider.ts} +19 -16
  187. package/src/Emailer/Sendgrid.ts +82 -59
  188. package/src/Emailer/fake.ts +3 -3
  189. package/src/MainFiberSet.ts +12 -10
  190. package/src/QueueMaker/SQLQueue.ts +153 -156
  191. package/src/QueueMaker/errors.ts +3 -1
  192. package/src/QueueMaker/memQueue.ts +113 -107
  193. package/src/QueueMaker/sbqueue.ts +78 -90
  194. package/src/RequestFiberSet.ts +13 -8
  195. package/src/{adapters/SQL → SQL}/Model.ts +42 -41
  196. package/src/ServiceBus.ts +219 -0
  197. package/src/Store/Cosmos/query.ts +216 -52
  198. package/src/Store/Cosmos.ts +493 -353
  199. package/src/Store/Disk.ts +109 -69
  200. package/src/Store/Memory.ts +365 -96
  201. package/src/Store/SQL/Pg.ts +363 -0
  202. package/src/Store/SQL/query.ts +603 -0
  203. package/src/Store/SQL.ts +735 -0
  204. package/src/Store/codeFilter.ts +8 -5
  205. package/src/Store/index.ts +21 -6
  206. package/src/Store/utils.ts +26 -24
  207. package/src/WorkflowEngineCosmos.ts +719 -0
  208. package/src/WorkflowEngineSqlite.ts +813 -0
  209. package/src/arbs.ts +5 -3
  210. package/src/{adapters/cosmos-client.ts → cosmos-client.ts} +5 -3
  211. package/src/errorReporter.ts +66 -76
  212. package/src/fileUtil.ts +1 -1
  213. package/src/index.ts +2 -1
  214. package/src/{api/internal → internal}/RequestContextMiddleware.ts +23 -6
  215. package/src/internal/auth.ts +272 -0
  216. package/src/{api/internal → internal}/events.ts +22 -13
  217. package/src/{api/layerUtils.ts → layerUtils.ts} +14 -10
  218. package/src/logger/jsonLogger.ts +4 -2
  219. package/src/logger/logFmtLogger.ts +2 -2
  220. package/src/logger/shared.ts +5 -4
  221. package/src/{adapters/memQueue.ts → memQueue.ts} +5 -4
  222. package/src/{adapters/mongo-client.ts → mongo-client.ts} +4 -2
  223. package/src/otel.ts +152 -0
  224. package/src/rateLimit.ts +34 -23
  225. package/src/{adapters/redis-client.ts → redis-client.ts} +7 -3
  226. package/src/{api/reportError.ts → reportError.ts} +3 -2
  227. package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +5 -4
  228. package/src/{api/routing → routing}/middleware/middleware.ts +62 -17
  229. package/src/routing/middleware.ts +4 -0
  230. package/src/{api/routing → routing}/schema/jwt.ts +2 -1
  231. package/src/{api/routing → routing}/utils.ts +2 -1
  232. package/src/routing.ts +768 -0
  233. package/src/test.ts +2 -2
  234. package/test/auth.test.ts +101 -0
  235. package/test/cluster-cosmos.test.ts +503 -0
  236. package/test/cluster-servicebus.test.ts +180 -0
  237. package/test/contextProvider.test.ts +15 -12
  238. package/test/controller.test.ts +28 -32
  239. package/test/cosmos-query.test.ts +159 -0
  240. package/test/dist/_check-agg-infer.test-d.d.ts +2 -0
  241. package/test/dist/_check-agg-infer.test-d.d.ts.map +1 -0
  242. package/test/dist/_check-agg-infer.test-d.js +19 -0
  243. package/test/dist/_check-proj-infer.test-d.d.ts +2 -0
  244. package/test/dist/_check-proj-infer.test-d.d.ts.map +1 -0
  245. package/test/dist/_check-proj-infer.test-d.js +16 -0
  246. package/test/dist/_check-tighten.test-d.d.ts +2 -0
  247. package/test/dist/_check-tighten.test-d.d.ts.map +1 -0
  248. package/test/dist/_check-tighten.test-d.js +21 -0
  249. package/test/dist/auth.test.d.ts.map +1 -0
  250. package/test/dist/cluster-cosmos.test.d.ts.map +1 -0
  251. package/test/dist/cluster-servicebus.test.d.ts.map +1 -0
  252. package/test/dist/contextProvider.test.d.ts.map +1 -1
  253. package/test/dist/controller.test.d.ts.map +1 -1
  254. package/test/dist/cosmos-query.test.d.ts.map +1 -0
  255. package/test/dist/date-query.test.d.ts.map +1 -0
  256. package/test/dist/fixtures.d.ts +30 -12
  257. package/test/dist/fixtures.d.ts.map +1 -1
  258. package/test/dist/fixtures.js +17 -10
  259. package/test/dist/query.test.d.ts.map +1 -1
  260. package/test/dist/rawQuery.test.d.ts.map +1 -1
  261. package/test/dist/repository-ext.test.d.ts.map +1 -0
  262. package/test/dist/requires.test.d.ts.map +1 -1
  263. package/test/dist/router-generator.test.d.ts.map +1 -0
  264. package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
  265. package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
  266. package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
  267. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  268. package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
  269. package/test/dist/sql-store.test.d.ts.map +1 -0
  270. package/test/dist/workflow-engine-cosmos.test.d.ts.map +1 -0
  271. package/test/dist/workflow-engine-sqlite.test.d.ts.map +1 -0
  272. package/test/fixtures.ts +16 -9
  273. package/test/layerUtils.test.ts +2 -2
  274. package/test/query.test.ts +905 -40
  275. package/test/rawQuery.test.ts +340 -22
  276. package/test/repository-ext.test.ts +62 -0
  277. package/test/requires.test.ts +10 -5
  278. package/test/router-generator.test.ts +187 -0
  279. package/test/routing-interruptibility.test.ts +66 -0
  280. package/test/rpc-context-map-streaming.test.ts +262 -0
  281. package/test/rpc-e2e-invalidation.test.ts +256 -0
  282. package/test/rpc-multi-middleware.test.ts +85 -10
  283. package/test/rpc-stream-fullstack.test.ts +304 -0
  284. package/test/sql-store.test.ts +1711 -0
  285. package/test/validateSample.test.ts +26 -14
  286. package/test/workflow-engine-cosmos.test.ts +354 -0
  287. package/test/workflow-engine-sqlite.test.ts +299 -0
  288. package/tsconfig.examples.json +1 -1
  289. package/tsconfig.json +2 -1
  290. package/tsconfig.json.bak +2 -2
  291. package/tsconfig.src.json +35 -35
  292. package/tsconfig.test.json +2 -2
  293. package/dist/Emailer/service.d.ts +0 -55
  294. package/dist/Emailer/service.d.ts.map +0 -1
  295. package/dist/Emailer/service.js +0 -6
  296. package/dist/Emailer.d.ts +0 -2
  297. package/dist/Emailer.d.ts.map +0 -1
  298. package/dist/Emailer.js +0 -2
  299. package/dist/Model/Repository/ext.d.ts +0 -41
  300. package/dist/Model/Repository/ext.d.ts.map +0 -1
  301. package/dist/Model/Repository/ext.js +0 -65
  302. package/dist/Model/Repository/internal/internal.d.ts +0 -59
  303. package/dist/Model/Repository/internal/internal.d.ts.map +0 -1
  304. package/dist/Model/Repository/internal/internal.js +0 -316
  305. package/dist/Model/Repository/legacy.d.ts +0 -19
  306. package/dist/Model/Repository/legacy.d.ts.map +0 -1
  307. package/dist/Model/Repository/legacy.js +0 -2
  308. package/dist/Model/Repository/makeRepo.d.ts +0 -49
  309. package/dist/Model/Repository/makeRepo.d.ts.map +0 -1
  310. package/dist/Model/Repository/makeRepo.js +0 -24
  311. package/dist/Model/Repository/service.d.ts +0 -89
  312. package/dist/Model/Repository/service.d.ts.map +0 -1
  313. package/dist/Model/Repository/service.js +0 -2
  314. package/dist/Model/Repository/validation.d.ts +0 -42
  315. package/dist/Model/Repository/validation.d.ts.map +0 -1
  316. package/dist/Model/Repository/validation.js +0 -32
  317. package/dist/Model/Repository.d.ts +0 -6
  318. package/dist/Model/Repository.d.ts.map +0 -1
  319. package/dist/Model/Repository.js +0 -6
  320. package/dist/Model/dsl.d.ts +0 -32
  321. package/dist/Model/dsl.d.ts.map +0 -1
  322. package/dist/Model/dsl.js +0 -44
  323. package/dist/Model/filter/filterApi.d.ts +0 -30
  324. package/dist/Model/filter/filterApi.d.ts.map +0 -1
  325. package/dist/Model/filter/filterApi.js +0 -2
  326. package/dist/Model/filter/types/errors.d.ts +0 -29
  327. package/dist/Model/filter/types/errors.d.ts.map +0 -1
  328. package/dist/Model/filter/types/errors.js +0 -2
  329. package/dist/Model/filter/types/fields.d.ts +0 -15
  330. package/dist/Model/filter/types/fields.d.ts.map +0 -1
  331. package/dist/Model/filter/types/fields.js +0 -2
  332. package/dist/Model/filter/types/path/common.d.ts +0 -316
  333. package/dist/Model/filter/types/path/common.d.ts.map +0 -1
  334. package/dist/Model/filter/types/path/common.js +0 -2
  335. package/dist/Model/filter/types/path/eager.d.ts +0 -95
  336. package/dist/Model/filter/types/path/eager.d.ts.map +0 -1
  337. package/dist/Model/filter/types/path/eager.js +0 -31
  338. package/dist/Model/filter/types/path/index.d.ts +0 -4
  339. package/dist/Model/filter/types/path/index.d.ts.map +0 -1
  340. package/dist/Model/filter/types/path/index.js +0 -3
  341. package/dist/Model/filter/types/utils.d.ts +0 -79
  342. package/dist/Model/filter/types/utils.d.ts.map +0 -1
  343. package/dist/Model/filter/types/utils.js +0 -2
  344. package/dist/Model/filter/types/validator.d.ts +0 -30
  345. package/dist/Model/filter/types/validator.d.ts.map +0 -1
  346. package/dist/Model/filter/types/validator.js +0 -2
  347. package/dist/Model/filter/types.d.ts +0 -5
  348. package/dist/Model/filter/types.d.ts.map +0 -1
  349. package/dist/Model/filter/types.js +0 -7
  350. package/dist/Model/query/dsl.d.ts +0 -248
  351. package/dist/Model/query/dsl.d.ts.map +0 -1
  352. package/dist/Model/query/dsl.js +0 -104
  353. package/dist/Model/query/new-kid-interpreter.d.ts +0 -28
  354. package/dist/Model/query/new-kid-interpreter.d.ts.map +0 -1
  355. package/dist/Model/query/new-kid-interpreter.js +0 -165
  356. package/dist/Model/query.d.ts +0 -15
  357. package/dist/Model/query.d.ts.map +0 -1
  358. package/dist/Model/query.js +0 -3
  359. package/dist/Model.d.ts +0 -4
  360. package/dist/Model.d.ts.map +0 -1
  361. package/dist/Model.js +0 -4
  362. package/dist/Operations.d.ts +0 -55
  363. package/dist/Operations.d.ts.map +0 -1
  364. package/dist/Operations.js +0 -102
  365. package/dist/OperationsRepo.d.ts +0 -41
  366. package/dist/OperationsRepo.d.ts.map +0 -1
  367. package/dist/OperationsRepo.js +0 -14
  368. package/dist/QueueMaker/service.d.ts +0 -11
  369. package/dist/QueueMaker/service.d.ts.map +0 -1
  370. package/dist/QueueMaker/service.js +0 -4
  371. package/dist/RequestContext.d.ts +0 -63
  372. package/dist/RequestContext.d.ts.map +0 -1
  373. package/dist/RequestContext.js +0 -49
  374. package/dist/Store/ContextMapContainer.d.ts +0 -14
  375. package/dist/Store/ContextMapContainer.d.ts.map +0 -1
  376. package/dist/Store/ContextMapContainer.js +0 -16
  377. package/dist/Store/service.d.ts +0 -108
  378. package/dist/Store/service.d.ts.map +0 -1
  379. package/dist/Store/service.js +0 -71
  380. package/dist/Store.d.ts +0 -2
  381. package/dist/Store.d.ts.map +0 -1
  382. package/dist/Store.js +0 -2
  383. package/dist/adapters/SQL/Model.d.ts +0 -479
  384. package/dist/adapters/SQL/Model.d.ts.map +0 -1
  385. package/dist/adapters/SQL/Model.js +0 -478
  386. package/dist/adapters/SQL.d.ts +0 -2
  387. package/dist/adapters/SQL.d.ts.map +0 -1
  388. package/dist/adapters/ServiceBus.d.ts +0 -58
  389. package/dist/adapters/ServiceBus.d.ts.map +0 -1
  390. package/dist/adapters/ServiceBus.js +0 -99
  391. package/dist/adapters/cosmos-client.d.ts +0 -14
  392. package/dist/adapters/cosmos-client.d.ts.map +0 -1
  393. package/dist/adapters/cosmos-client.js +0 -9
  394. package/dist/adapters/index.d.ts +0 -2
  395. package/dist/adapters/index.d.ts.map +0 -1
  396. package/dist/adapters/index.js +0 -2
  397. package/dist/adapters/logger.d.ts +0 -9
  398. package/dist/adapters/logger.d.ts.map +0 -1
  399. package/dist/adapters/logger.js +0 -3
  400. package/dist/adapters/memQueue.d.ts +0 -13
  401. package/dist/adapters/memQueue.d.ts.map +0 -1
  402. package/dist/adapters/memQueue.js +0 -20
  403. package/dist/adapters/mongo-client.d.ts +0 -10
  404. package/dist/adapters/mongo-client.d.ts.map +0 -1
  405. package/dist/adapters/mongo-client.js +0 -13
  406. package/dist/adapters/redis-client.d.ts +0 -39
  407. package/dist/adapters/redis-client.d.ts.map +0 -1
  408. package/dist/adapters/redis-client.js +0 -94
  409. package/dist/api/ContextProvider.d.ts +0 -31
  410. package/dist/api/ContextProvider.d.ts.map +0 -1
  411. package/dist/api/ContextProvider.js +0 -38
  412. package/dist/api/codec.d.ts +0 -5
  413. package/dist/api/codec.d.ts.map +0 -1
  414. package/dist/api/codec.js +0 -5
  415. package/dist/api/internal/RequestContextMiddleware.d.ts +0 -5
  416. package/dist/api/internal/RequestContextMiddleware.d.ts.map +0 -1
  417. package/dist/api/internal/RequestContextMiddleware.js +0 -35
  418. package/dist/api/internal/auth.d.ts +0 -15
  419. package/dist/api/internal/auth.d.ts.map +0 -1
  420. package/dist/api/internal/auth.js +0 -47
  421. package/dist/api/internal/events.d.ts +0 -9
  422. package/dist/api/internal/events.d.ts.map +0 -1
  423. package/dist/api/internal/events.js +0 -42
  424. package/dist/api/internal/health.d.ts +0 -3
  425. package/dist/api/internal/health.d.ts.map +0 -1
  426. package/dist/api/internal/health.js +0 -5
  427. package/dist/api/layerUtils.d.ts +0 -24
  428. package/dist/api/layerUtils.d.ts.map +0 -1
  429. package/dist/api/layerUtils.js +0 -16
  430. package/dist/api/middlewares.d.ts +0 -10
  431. package/dist/api/middlewares.d.ts.map +0 -1
  432. package/dist/api/reportError.d.ts +0 -4
  433. package/dist/api/reportError.d.ts.map +0 -1
  434. package/dist/api/reportError.js +0 -27
  435. package/dist/api/routing/middleware/RouterMiddleware.d.ts +0 -15
  436. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +0 -1
  437. package/dist/api/routing/middleware/middleware.d.ts +0 -9
  438. package/dist/api/routing/middleware/middleware.d.ts.map +0 -1
  439. package/dist/api/routing/middleware/middleware.js +0 -92
  440. package/dist/api/routing/middleware.d.ts +0 -4
  441. package/dist/api/routing/middleware.d.ts.map +0 -1
  442. package/dist/api/routing/schema/jwt.d.ts +0 -4
  443. package/dist/api/routing/schema/jwt.d.ts.map +0 -1
  444. package/dist/api/routing/schema/jwt.js +0 -12
  445. package/dist/api/routing/tsort.d.ts +0 -8
  446. package/dist/api/routing/tsort.d.ts.map +0 -1
  447. package/dist/api/routing/tsort.js +0 -51
  448. package/dist/api/routing/utils.d.ts +0 -19
  449. package/dist/api/routing/utils.d.ts.map +0 -1
  450. package/dist/api/routing/utils.js +0 -44
  451. package/dist/api/routing.d.ts +0 -138
  452. package/dist/api/routing.d.ts.map +0 -1
  453. package/dist/api/routing.js +0 -166
  454. package/dist/api/setupRequest.d.ts +0 -12
  455. package/dist/api/setupRequest.d.ts.map +0 -1
  456. package/dist/api/setupRequest.js +0 -44
  457. package/dist/api/util.d.ts +0 -3
  458. package/dist/api/util.d.ts.map +0 -1
  459. package/dist/api/util.js +0 -14
  460. package/eslint.config.mjs +0 -24
  461. package/src/Emailer/service.ts +0 -52
  462. package/src/Emailer.ts +0 -1
  463. package/src/Model/Repository/ext.ts +0 -283
  464. package/src/Model/Repository/internal/internal.ts +0 -577
  465. package/src/Model/Repository/legacy.ts +0 -27
  466. package/src/Model/Repository/makeRepo.ts +0 -139
  467. package/src/Model/Repository/service.ts +0 -627
  468. package/src/Model/Repository/validation.ts +0 -31
  469. package/src/Model/Repository.ts +0 -5
  470. package/src/Model/dsl.ts +0 -128
  471. package/src/Model/filter/filterApi.ts +0 -60
  472. package/src/Model/filter/types/errors.ts +0 -47
  473. package/src/Model/filter/types/fields.ts +0 -50
  474. package/src/Model/filter/types/path/common.ts +0 -404
  475. package/src/Model/filter/types/path/eager.ts +0 -298
  476. package/src/Model/filter/types/path/index.ts +0 -4
  477. package/src/Model/filter/types/utils.ts +0 -128
  478. package/src/Model/filter/types/validator.ts +0 -46
  479. package/src/Model/filter/types.ts +0 -6
  480. package/src/Model/query/dsl.ts +0 -2110
  481. package/src/Model/query/new-kid-interpreter.ts +0 -210
  482. package/src/Model/query.ts +0 -13
  483. package/src/Model.ts +0 -3
  484. package/src/Operations.ts +0 -235
  485. package/src/OperationsRepo.ts +0 -16
  486. package/src/QueueMaker/service.ts +0 -17
  487. package/src/RequestContext.ts +0 -63
  488. package/src/Store/ContextMapContainer.ts +0 -20
  489. package/src/Store/service.ts +0 -184
  490. package/src/Store.ts +0 -1
  491. package/src/adapters/ServiceBus.ts +0 -209
  492. package/src/adapters/index.ts +0 -0
  493. package/src/adapters/logger.ts +0 -3
  494. package/src/api/internal/auth.ts +0 -68
  495. package/src/api/routing/middleware.ts +0 -6
  496. package/src/api/routing.ts +0 -598
  497. package/src/api/setupRequest.ts +0 -84
  498. /package/src/{adapters/SQL.ts → SQL.ts} +0 -0
  499. /package/src/{api/codec.ts → codec.ts} +0 -0
  500. /package/src/{api/internal → internal}/health.ts +0 -0
  501. /package/src/{api/middlewares.ts → middlewares.ts} +0 -0
  502. /package/src/{api/routing → routing}/tsort.ts +0 -0
  503. /package/src/{api/util.ts → util.ts} +0 -0
package/src/test.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { S } from "effect-app"
1
+ import * as S from "effect-app/Schema"
2
2
  import { copy } from "effect-app/utils"
3
3
  import { generate } from "./arbs.js"
4
4
 
@@ -16,7 +16,7 @@ export const createRandomInstance = <A extends object, I, R>(s: S.Codec<A, I, R>
16
16
  /**
17
17
  * Like `createRandomInstance`, but takes encoded values rather than decoded ones.
18
18
  */
19
- export const createRandomInstanceI = <A extends object, I>(s: S.Codec<A, I, never> & { fields: S.Struct.Fields }) => {
19
+ export const createRandomInstanceI = <A extends object, I>(s: S.Codec<A, I> & { fields: S.Struct.Fields }) => {
20
20
  const gen = generate(S.toArbitrary(s))
21
21
  const encode = S.encodeSync(s)
22
22
  const decode = S.decodeSync(s)
@@ -0,0 +1,101 @@
1
+ import { describe, expect, it } from "@effect/vitest"
2
+ import * as Effect from "effect-app/Effect"
3
+ import { HttpHeaders } from "effect-app/http"
4
+ import { SignJWT } from "jose"
5
+ import { checkJWTI, InvalidRequestError, InvalidTokenError, UnauthorizedError } from "../src/internal/auth.js"
6
+
7
+ const issuer = "https://issuer.example.com/"
8
+ const audience = "effect-app"
9
+ const secret = "test-secret-test-secret-test-secret"
10
+
11
+ const makeToken = () =>
12
+ new SignJWT({ scope: "read:all" })
13
+ .setProtectedHeader({ alg: "HS256", typ: "at+jwt" })
14
+ .setIssuer(issuer)
15
+ .setAudience(audience)
16
+ .setIssuedAt()
17
+ .setExpirationTime("10m")
18
+ .sign(new TextEncoder().encode(secret))
19
+
20
+ describe("checkJWTI", () => {
21
+ it.effect(
22
+ "validates a bearer token from headers",
23
+ Effect.fnUntraced(function*() {
24
+ const token = yield* Effect.promise(() => makeToken())
25
+
26
+ yield* checkJWTI({
27
+ audience,
28
+ issuer,
29
+ secret,
30
+ strict: true,
31
+ tokenSigningAlg: "HS256"
32
+ })(HttpHeaders.fromRecordUnsafe({ authorization: `Bearer ${token}` }))
33
+ })
34
+ )
35
+
36
+ it.effect(
37
+ "fails on malformed authorization headers",
38
+ Effect.fnUntraced(function*() {
39
+ const error = yield* Effect.flip(
40
+ checkJWTI({
41
+ audience,
42
+ issuer,
43
+ secret,
44
+ tokenSigningAlg: "HS256"
45
+ })(HttpHeaders.fromRecordUnsafe({ authorization: "Basic abc" }))
46
+ )
47
+
48
+ expect(error).toBeInstanceOf(InvalidRequestError)
49
+ expect(error.status).toBe(400)
50
+ })
51
+ )
52
+
53
+ it.effect(
54
+ "fails when the token is missing",
55
+ Effect.fnUntraced(function*() {
56
+ const error = yield* Effect.flip(
57
+ checkJWTI({
58
+ audience,
59
+ issuer,
60
+ secret,
61
+ tokenSigningAlg: "HS256"
62
+ })(HttpHeaders.empty)
63
+ )
64
+
65
+ expect(error).toBeInstanceOf(UnauthorizedError)
66
+ expect(error.status).toBe(401)
67
+ })
68
+ )
69
+
70
+ it.effect(
71
+ "allows missing tokens when auth is optional",
72
+ Effect.fnUntraced(function*() {
73
+ yield* checkJWTI({
74
+ audience,
75
+ authRequired: false,
76
+ issuer,
77
+ secret,
78
+ tokenSigningAlg: "HS256"
79
+ })(HttpHeaders.empty)
80
+ })
81
+ )
82
+
83
+ it.effect(
84
+ "fails when the token signature is invalid",
85
+ Effect.fnUntraced(function*() {
86
+ const token = yield* Effect.promise(() => makeToken())
87
+
88
+ const error = yield* Effect.flip(
89
+ checkJWTI({
90
+ audience,
91
+ issuer,
92
+ secret: "wrong-secret-wrong-secret-wrong-secret",
93
+ tokenSigningAlg: "HS256"
94
+ })(HttpHeaders.fromRecordUnsafe({ authorization: `Bearer ${token}` }))
95
+ )
96
+
97
+ expect(error).toBeInstanceOf(InvalidTokenError)
98
+ expect(error.status).toBe(401)
99
+ })
100
+ )
101
+ })
@@ -0,0 +1,503 @@
1
+ import { assert, describe, expect, it } from "@effect/vitest"
2
+ import { Context, Duration, Effect, Exit, Fiber, Latch, Layer, Option, Redacted, Schema } from "effect"
3
+ import { TestClock } from "effect/testing"
4
+ import { ClusterSchema, ClusterWorkflowEngine, Entity, EntityAddress, EntityId, EntityType, Envelope, Message, MessageStorage, Reply, Runner, RunnerAddress, RunnerHealth, Runners, RunnerStorage, ShardId, Sharding, ShardingConfig, Snowflake } from "effect/unstable/cluster"
5
+ import { Headers } from "effect/unstable/http"
6
+ import { Rpc, RpcSchema } from "effect/unstable/rpc"
7
+ import { DurableDeferred, Workflow } from "effect/unstable/workflow"
8
+ import { layerCosmos } from "../src/ClusterCosmos.js"
9
+
10
+ const cosmosUrl = process.env["COSMOS_TEST_URL"]
11
+ const cosmosDb = process.env["COSMOS_TEST_DB"] ?? "cluster-test"
12
+ const testRunId = `${Date.now()}-${process.pid}-${Math.random().toString(16).slice(2)}`
13
+ const runnerPortBase = 10000 + Date.now() % 40000
14
+
15
+ const layerFor = () =>
16
+ layerCosmos({
17
+ url: Redacted.make(cosmosUrl ?? ""),
18
+ dbName: cosmosDb,
19
+ prefix: "test-cluster-"
20
+ })
21
+ .pipe(
22
+ Layer.provideMerge(Snowflake.layerGenerator),
23
+ Layer.provide(ShardingConfig.layerDefaults)
24
+ )
25
+
26
+ describe.skipIf(!cosmosUrl)("ClusterCosmos MessageStorage", () => {
27
+ it.effect("deduplicates keyed requests and returns the last reply", () =>
28
+ Effect
29
+ .gen(function*() {
30
+ const storage = yield* MessageStorage.MessageStorage
31
+ const shardId = testShardId("message-duplicate")
32
+ const primaryKey = `primary/${testRunId}\\with?illegal#chars`
33
+ const request = yield* makeStreamRequest(primaryKey, shardId)
34
+
35
+ const saved = yield* storage.saveRequest(request)
36
+ assert.strictEqual(saved._tag, "Success")
37
+
38
+ const chunk = yield* makeChunkReply(request, 0)
39
+ yield* storage.saveReply(chunk)
40
+
41
+ const duplicateWithChunk = yield* storage.saveRequest(
42
+ yield* makeStreamRequest(primaryKey, shardId)
43
+ )
44
+ assert(duplicateWithChunk._tag === "Duplicate" && Option.isSome(duplicateWithChunk.lastReceivedReply))
45
+ assert.strictEqual(duplicateWithChunk.lastReceivedReply.value._tag, "Chunk")
46
+
47
+ const ackChunk = yield* makeAckChunk(request, chunk)
48
+ yield* storage.saveEnvelope(ackChunk)
49
+ const repliesAfterAck = yield* storage.repliesFor([request])
50
+ assert.strictEqual(repliesAfterAck.length, 0)
51
+
52
+ yield* storage.saveReply(yield* makeStreamReply(request))
53
+ const duplicateWithExit = yield* storage.saveRequest(
54
+ yield* makeStreamRequest(primaryKey, shardId)
55
+ )
56
+ assert(duplicateWithExit._tag === "Duplicate" && Option.isSome(duplicateWithExit.lastReceivedReply))
57
+ assert.strictEqual(duplicateWithExit.lastReceivedReply.value._tag, "WithExit")
58
+ })
59
+ .pipe(Effect.provide(layerFor())))
60
+
61
+ it.effect("marks reads, resets shards, and excludes completed requests", () =>
62
+ Effect
63
+ .gen(function*() {
64
+ const storage = yield* MessageStorage.MessageStorage
65
+ const shardId = testShardId("message-unprocessed")
66
+ const request1 = yield* makeRequest({ payload: { id: 1 }, shardId })
67
+ const request2 = yield* makeRequest({ payload: { id: 2 }, shardId })
68
+ assert.strictEqual((yield* storage.saveRequest(request1))._tag, "Success")
69
+ assert.strictEqual((yield* storage.saveRequest(request2))._tag, "Success")
70
+
71
+ let messages = yield* storage.unprocessedMessages([request1.envelope.address.shardId])
72
+ assert.deepStrictEqual(messages.map((message) => requestPayloadId(message)).sort(), [1, 2])
73
+
74
+ messages = yield* storage.unprocessedMessages([request1.envelope.address.shardId])
75
+ assert.strictEqual(messages.length, 0)
76
+
77
+ yield* storage.resetShards([request1.envelope.address.shardId])
78
+ messages = yield* storage.unprocessedMessages([request1.envelope.address.shardId])
79
+ assert.deepStrictEqual(messages.map((message) => requestPayloadId(message)).sort(), [1, 2])
80
+
81
+ yield* storage.saveReply(yield* makeReply(request1))
82
+ yield* storage.resetShards([request1.envelope.address.shardId])
83
+ messages = yield* storage.unprocessedMessages([request1.envelope.address.shardId])
84
+ assert.deepStrictEqual(messages.map((message) => requestPayloadId(message)), [2])
85
+ })
86
+ .pipe(Effect.provide(layerFor())))
87
+
88
+ it.effect("notifies registered reply handlers", () =>
89
+ Effect
90
+ .gen(function*() {
91
+ const storage = yield* MessageStorage.MessageStorage
92
+ const latch = yield* Latch.make()
93
+ const request = yield* makeRequest({ shardId: testShardId("message-handler") })
94
+ yield* storage.saveRequest(request)
95
+
96
+ const fiber = yield* storage
97
+ .registerReplyHandler(
98
+ new Message.OutgoingRequest({
99
+ ...request,
100
+ respond: () => latch.open
101
+ })
102
+ )
103
+ .pipe(Effect.forkChild)
104
+
105
+ yield* TestClock.adjust(1)
106
+ yield* storage.saveReply(yield* makeReply(request))
107
+ yield* latch.await
108
+ yield* Fiber.await(fiber)
109
+ })
110
+ .pipe(Effect.provide(layerFor())))
111
+ })
112
+
113
+ describe.skipIf(!cosmosUrl)("ClusterCosmos RunnerStorage", () => {
114
+ it.effect("registers runners and tracks health", () =>
115
+ Effect
116
+ .gen(function*() {
117
+ const storage = yield* RunnerStorage.RunnerStorage
118
+ const runnerAddress = testRunnerAddress(1)
119
+ const runner = Runner.make({
120
+ address: runnerAddress,
121
+ groups: ["default"],
122
+ weight: 1
123
+ })
124
+
125
+ const machineId1 = yield* storage.register(runner, true)
126
+ const machineId2 = yield* storage.register(runner, true)
127
+ assert.deepStrictEqual(machineId2, machineId1)
128
+ expect(runnerStatus(yield* storage.getRunners, runnerAddress)).toEqual([runner, true])
129
+
130
+ yield* storage.setRunnerHealth(runnerAddress, false)
131
+ expect(runnerStatus(yield* storage.getRunners, runnerAddress)).toEqual([runner, false])
132
+
133
+ yield* storage.unregister(runnerAddress)
134
+ expect(runnerStatus(yield* storage.getRunners, runnerAddress)).toBeUndefined()
135
+ })
136
+ .pipe(Effect.provide(layerFor())))
137
+
138
+ it.effect("acquires, refreshes, releases, and re-acquires shard locks", () =>
139
+ Effect
140
+ .gen(function*() {
141
+ const storage = yield* RunnerStorage.RunnerStorage
142
+ const runnerAddress1 = testRunnerAddress(2)
143
+ const runnerAddress2 = testRunnerAddress(3)
144
+ const shards = [
145
+ testShardId("runner-locks", 1),
146
+ testShardId("runner-locks", 2),
147
+ testShardId("runner-locks", 3)
148
+ ]
149
+
150
+ let acquired = yield* storage.acquire(runnerAddress1, shards)
151
+ assert.deepStrictEqual(acquired.map((shard) => shard.id), [1, 2, 3])
152
+
153
+ acquired = yield* storage.acquire(runnerAddress2, shards)
154
+ assert.deepStrictEqual(acquired.map((shard) => shard.id), [])
155
+
156
+ const refreshed = yield* storage.refresh(runnerAddress1, shards)
157
+ assert.deepStrictEqual(refreshed.map((shard) => shard.id), [1, 2, 3])
158
+
159
+ yield* storage.release(runnerAddress1, testShardId("runner-locks", 2))
160
+ acquired = yield* storage.acquire(runnerAddress2, shards)
161
+ assert.deepStrictEqual(acquired.map((shard) => shard.id), [2])
162
+
163
+ yield* storage.releaseAll(runnerAddress1)
164
+ acquired = yield* storage.acquire(runnerAddress2, shards)
165
+ assert.deepStrictEqual(acquired.map((shard) => shard.id), [1, 2, 3])
166
+ })
167
+ .pipe(Effect.provide(layerFor())))
168
+ })
169
+
170
+ describe.skipIf(!cosmosUrl)("ClusterCosmos Sharding RPC", () => {
171
+ it.effect("runs persisted entity RPCs through Cosmos-backed cluster storage", () =>
172
+ Effect
173
+ .gen(function*() {
174
+ yield* TestClock.adjust(1)
175
+ const sharding = yield* Sharding.Sharding
176
+ const makeClient = yield* CosmosRpcEntity.client
177
+ const entityId = `entity/${testRunId}\\with?illegal#chars`
178
+ const shardId = sharding.getShardId(EntityId.make(entityId), testShardGroup("rpc"))
179
+ yield* waitForShard(sharding, shardId)
180
+ assert.isTrue(sharding.hasShardId(shardId))
181
+ const client = makeClient(entityId)
182
+
183
+ const user = yield* client.GetCosmosUser({ id: 42 })
184
+ expect(user).toEqual(new CosmosRpcUser({ id: 42, name: "User 42" }))
185
+
186
+ const primaryKey = `rpc/${testRunId}\\with?illegal#chars`
187
+ const first = yield* client.CosmosRequestWithKey({ key: primaryKey })
188
+ const duplicate = yield* client.CosmosRequestWithKey({ key: primaryKey })
189
+
190
+ assert.strictEqual(first, primaryKey)
191
+ assert.strictEqual(duplicate, primaryKey)
192
+ })
193
+ .pipe(Effect.provide(clusterRpcLayer("rpc"))), 20000)
194
+ })
195
+
196
+ describe.skipIf(!cosmosUrl)("ClusterCosmos Workflow", () => {
197
+ it.live("resumes a running workflow suspended on a durable deferred", () =>
198
+ Effect
199
+ .gen(function*() {
200
+ const sharding = yield* Sharding.Sharding
201
+ const payload = { id: `deferred/${testRunId}\\with?illegal#chars` }
202
+ const executionId = yield* CosmosDeferredWorkflow.executionId(payload)
203
+
204
+ const fiber = yield* CosmosDeferredWorkflow.execute(payload).pipe(Effect.forkScoped)
205
+ yield* waitForDeferredWorkflowSuspended(executionId)
206
+
207
+ const token = yield* DurableDeferred.tokenFromPayload(CosmosDeferred, {
208
+ workflow: CosmosDeferredWorkflow,
209
+ payload
210
+ })
211
+ yield* DurableDeferred.done(CosmosDeferred, { token, exit: Exit.succeed("resolved") })
212
+ yield* sharding.pollStorage
213
+
214
+ const value = yield* Fiber.join(fiber).pipe(Effect.timeout(Duration.seconds(15)))
215
+ assert.strictEqual(value, `${payload.id}:resolved`)
216
+ assert.strictEqual(yield* waitForDeferredWorkflowComplete(executionId), `${payload.id}:resolved`)
217
+ })
218
+ .pipe(Effect.provide(clusterWorkflowLayer())), 30000)
219
+ })
220
+
221
+ const GetUserRpc = Rpc.make("GetUser", {
222
+ payload: { id: Schema.Number }
223
+ })
224
+
225
+ class CosmosRpcUser extends Schema.Class<CosmosRpcUser>("CosmosRpcUser")({
226
+ id: Schema.Number,
227
+ name: Schema.String
228
+ }) {}
229
+
230
+ const CosmosRpcEntity = Entity
231
+ .make("CosmosRpcEntity", [
232
+ Rpc.make("GetCosmosUser", {
233
+ success: CosmosRpcUser,
234
+ payload: { id: Schema.Number }
235
+ }),
236
+ Rpc.make("CosmosRequestWithKey", {
237
+ success: Schema.String,
238
+ payload: { key: Schema.String },
239
+ primaryKey: ({ key }) => key
240
+ })
241
+ ])
242
+ .annotate(ClusterSchema.ShardGroup, () => testShardGroup("rpc"))
243
+ .annotateRpcs(ClusterSchema.Persisted, true)
244
+
245
+ const CosmosRpcEntityLayer = CosmosRpcEntity.toLayer(
246
+ Effect.succeed(
247
+ CosmosRpcEntity.of({
248
+ GetCosmosUser: (envelope) =>
249
+ Effect.succeed(new CosmosRpcUser({ id: envelope.payload.id, name: `User ${envelope.payload.id}` })),
250
+ CosmosRequestWithKey: (envelope) => Effect.succeed(envelope.payload.key)
251
+ })
252
+ )
253
+ )
254
+
255
+ const CosmosDeferred = DurableDeferred.make("ClusterCosmos/Deferred", { success: Schema.String })
256
+
257
+ const CosmosDeferredWorkflow = Workflow
258
+ .make({
259
+ name: "ClusterCosmos/DeferredWorkflow",
260
+ payload: { id: Schema.String },
261
+ success: Schema.String,
262
+ idempotencyKey: ({ id }) => id
263
+ })
264
+ .annotate(ClusterSchema.ShardGroup, () => testShardGroup("workflow"))
265
+
266
+ const CosmosDeferredWorkflowLayer = CosmosDeferredWorkflow.toLayer(Effect.fnUntraced(function*({ id }) {
267
+ const value = yield* DurableDeferred.await(CosmosDeferred)
268
+ return `${id}:${value}`
269
+ }))
270
+
271
+ class StreamRpc extends Rpc.make("StreamTest", {
272
+ success: RpcSchema.Stream(Schema.Void, Schema.Never),
273
+ payload: {
274
+ id: Schema.String
275
+ },
276
+ primaryKey: (value) => value.id.toString()
277
+ }) {}
278
+
279
+ const makeRequest = Effect.fnUntraced(function*(options?: {
280
+ readonly payload?: { readonly id: number }
281
+ readonly shardId?: ShardId.ShardId
282
+ }) {
283
+ const snowflake = yield* Snowflake.Generator
284
+ return new Message.OutgoingRequest({
285
+ envelope: Envelope.makeRequest<typeof GetUserRpc>({
286
+ requestId: snowflake.nextUnsafe(),
287
+ address: EntityAddress.make({
288
+ shardId: options?.shardId ?? testShardId("default"),
289
+ entityType: EntityType.make("test"),
290
+ entityId: EntityId.make("1")
291
+ }),
292
+ tag: GetUserRpc._tag,
293
+ payload: options?.payload ?? { id: 123 },
294
+ traceId: "noop",
295
+ spanId: "noop",
296
+ sampled: false,
297
+ headers: Headers.empty
298
+ }),
299
+ annotations: GetUserRpc.annotations,
300
+ context: Context.empty(),
301
+ rpc: GetUserRpc,
302
+ lastReceivedReply: Option.none(),
303
+ respond() {
304
+ return Effect.void
305
+ }
306
+ })
307
+ })
308
+
309
+ const makeStreamRequest = Effect.fnUntraced(function*(id: string, shardId = testShardId("stream")) {
310
+ const snowflake = yield* Snowflake.Generator
311
+ return new Message.OutgoingRequest({
312
+ envelope: Envelope.makeRequest<typeof StreamRpc>({
313
+ requestId: snowflake.nextUnsafe(),
314
+ address: EntityAddress.make({
315
+ shardId,
316
+ entityType: EntityType.make("test"),
317
+ entityId: EntityId.make("1")
318
+ }),
319
+ tag: StreamRpc._tag,
320
+ payload: StreamRpc.payloadSchema.make({ id }),
321
+ traceId: "noop",
322
+ spanId: "noop",
323
+ sampled: false,
324
+ headers: Headers.empty
325
+ }),
326
+ annotations: StreamRpc.annotations,
327
+ context: Context.empty(),
328
+ rpc: StreamRpc,
329
+ lastReceivedReply: Option.none(),
330
+ respond() {
331
+ return Effect.void
332
+ }
333
+ })
334
+ })
335
+
336
+ const makeReply = Effect.fnUntraced(function*(request: Message.OutgoingRequest<typeof GetUserRpc>) {
337
+ const snowflake = yield* Snowflake.Generator
338
+ return new Reply.ReplyWithContext({
339
+ reply: new Reply.WithExit<typeof GetUserRpc>({
340
+ id: snowflake.nextUnsafe(),
341
+ requestId: request.envelope.requestId,
342
+ exit: Exit.void
343
+ }),
344
+ context: request.context,
345
+ rpc: request.rpc
346
+ })
347
+ })
348
+
349
+ const makeStreamReply = Effect.fnUntraced(function*(request: Message.OutgoingRequest<typeof StreamRpc>) {
350
+ const snowflake = yield* Snowflake.Generator
351
+ return new Reply.ReplyWithContext({
352
+ reply: new Reply.WithExit<typeof StreamRpc>({
353
+ id: snowflake.nextUnsafe(),
354
+ requestId: request.envelope.requestId,
355
+ exit: Exit.void
356
+ }),
357
+ context: request.context,
358
+ rpc: request.rpc
359
+ })
360
+ })
361
+
362
+ const makeAckChunk = Effect.fnUntraced(function*(
363
+ request: Message.OutgoingRequest<typeof StreamRpc>,
364
+ chunk: Reply.ReplyWithContext<typeof StreamRpc>
365
+ ) {
366
+ const snowflake = yield* Snowflake.Generator
367
+ return new Message.OutgoingEnvelope({
368
+ envelope: new Envelope.AckChunk({
369
+ id: snowflake.nextUnsafe(),
370
+ address: request.envelope.address,
371
+ requestId: chunk.reply.requestId,
372
+ replyId: chunk.reply.id
373
+ }),
374
+ rpc: request.rpc
375
+ })
376
+ })
377
+
378
+ const makeChunkReply = Effect.fnUntraced(function*(
379
+ request: Message.OutgoingRequest<typeof StreamRpc>,
380
+ sequence: number
381
+ ) {
382
+ const snowflake = yield* Snowflake.Generator
383
+ return new Reply.ReplyWithContext({
384
+ reply: new Reply.Chunk<typeof StreamRpc>({
385
+ id: snowflake.nextUnsafe(),
386
+ requestId: request.envelope.requestId,
387
+ sequence,
388
+ values: [undefined]
389
+ }),
390
+ context: request.context,
391
+ rpc: request.rpc
392
+ })
393
+ })
394
+
395
+ const requestPayloadId = (message: Message.Incoming<never>) => {
396
+ if (message.envelope._tag !== "Request") {
397
+ throw new Error(`Expected Request envelope`)
398
+ }
399
+ const envelope = message.envelope
400
+ assert(typeof envelope.payload === "object" && envelope.payload !== null)
401
+ assert("id" in envelope.payload)
402
+ assert.strictEqual(typeof envelope.payload.id, "number")
403
+ return envelope.payload.id
404
+ }
405
+
406
+ const testShardId = (label: string, id = 1) => ShardId.make(`cluster-cosmos-${testRunId}-${label}`, id)
407
+
408
+ const testShardGroup = (label: string) => `cluster-cosmos-${testRunId}-${label}`
409
+
410
+ const testRunnerAddress = (offset: number) => RunnerAddress.make("localhost", runnerPortBase + offset)
411
+
412
+ const runnerStatus = (
413
+ runners: ReadonlyArray<readonly [Runner.Runner, boolean]>,
414
+ address: RunnerAddress.RunnerAddress
415
+ ) => runners.find(([runner]) => runner.address.host === address.host && runner.address.port === address.port)
416
+
417
+ const clusterRpcLayer = (label: string) => {
418
+ const shardGroup = testShardGroup(label)
419
+ return CosmosRpcEntityLayer.pipe(
420
+ Layer.provideMerge(Sharding.layer),
421
+ Layer.provide(Runners.layerNoop),
422
+ Layer.provide(RunnerHealth.layerNoop),
423
+ Layer.provide(layerCosmos({
424
+ url: Redacted.make(cosmosUrl ?? ""),
425
+ dbName: cosmosDb,
426
+ prefix: "test-cluster-"
427
+ })),
428
+ Layer.provide(ShardingConfig.layer({
429
+ runnerAddress: Option.some(testRunnerAddress(10)),
430
+ shardsPerGroup: 1,
431
+ availableShardGroups: [shardGroup],
432
+ assignedShardGroups: [shardGroup],
433
+ entityTerminationTimeout: 0,
434
+ entityMessagePollInterval: 50,
435
+ entityReplyPollInterval: 50,
436
+ refreshAssignmentsInterval: 0,
437
+ sendRetryInterval: 50
438
+ }))
439
+ )
440
+ }
441
+
442
+ const clusterWorkflowLayer = () =>
443
+ CosmosDeferredWorkflowLayer.pipe(
444
+ Layer.provideMerge(
445
+ ClusterWorkflowEngine.layer.pipe(
446
+ Layer.provideMerge(Sharding.layer),
447
+ Layer.provide(Runners.layerNoop),
448
+ Layer.provide(RunnerHealth.layerNoop),
449
+ Layer.provide(layerCosmos({
450
+ url: Redacted.make(cosmosUrl ?? ""),
451
+ dbName: cosmosDb,
452
+ prefix: "test-cluster-"
453
+ })),
454
+ Layer.provide(ShardingConfig.layer({
455
+ runnerAddress: Option.some(testRunnerAddress(20)),
456
+ shardsPerGroup: 1,
457
+ availableShardGroups: [testShardGroup("workflow")],
458
+ assignedShardGroups: [testShardGroup("workflow")],
459
+ entityTerminationTimeout: 0,
460
+ entityMessagePollInterval: 50,
461
+ entityReplyPollInterval: 50,
462
+ refreshAssignmentsInterval: 0,
463
+ sendRetryInterval: 50
464
+ }))
465
+ )
466
+ )
467
+ )
468
+
469
+ const waitForDeferredWorkflowSuspended = (executionId: string) =>
470
+ Effect.gen(function*() {
471
+ const sharding = yield* Sharding.Sharding
472
+ for (let i = 0; i < 100; i++) {
473
+ yield* sharding.pollStorage
474
+ const polled = yield* CosmosDeferredWorkflow.poll(executionId)
475
+ if (Option.isSome(polled) && polled.value._tag === "Suspended") return
476
+ yield* Effect.sleep(Duration.millis(100))
477
+ }
478
+ return yield* Effect.fail(new Error(`Workflow ${executionId} did not suspend`))
479
+ })
480
+
481
+ const waitForDeferredWorkflowComplete = (executionId: string) =>
482
+ Effect.gen(function*() {
483
+ const sharding = yield* Sharding.Sharding
484
+ for (let i = 0; i < 100; i++) {
485
+ yield* sharding.pollStorage
486
+ const polled = yield* CosmosDeferredWorkflow.poll(executionId)
487
+ if (Option.isSome(polled) && polled.value._tag === "Complete") {
488
+ const exit = polled.value.exit
489
+ assert(Exit.isSuccess(exit))
490
+ return exit.value
491
+ }
492
+ yield* Effect.sleep(Duration.millis(100))
493
+ }
494
+ return yield* Effect.fail(new Error(`Workflow ${executionId} did not complete`))
495
+ })
496
+
497
+ const waitForShard = (sharding: Sharding.Sharding["Service"], shardId: ShardId.ShardId) =>
498
+ Effect.gen(function*() {
499
+ for (let i = 0; i < 30; i++) {
500
+ if (sharding.hasShardId(shardId)) return
501
+ yield* Effect.promise<void>(() => new Promise((resolve) => setTimeout(resolve, 100)))
502
+ }
503
+ })