@effect-app/infra 4.0.0-beta.31 → 4.0.0-beta.310

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 (473) hide show
  1. package/CHANGELOG.md +2361 -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 +31 -42
  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 +253 -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 +472 -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 +2 -2
  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.map +1 -1
  109. package/dist/middlewares.d.ts.map +1 -0
  110. package/dist/{api/middlewares.js → middlewares.js} +1 -1
  111. package/dist/{adapters/mongo-client.d.ts → mongo-client.d.ts} +3 -2
  112. package/dist/mongo-client.d.ts.map +1 -0
  113. package/dist/mongo-client.js +15 -0
  114. package/dist/otel.d.ts +75 -0
  115. package/dist/otel.d.ts.map +1 -0
  116. package/dist/otel.js +84 -0
  117. package/dist/rateLimit.d.ts +11 -3
  118. package/dist/rateLimit.d.ts.map +1 -1
  119. package/dist/rateLimit.js +7 -12
  120. package/dist/{adapters/redis-client.d.ts → redis-client.d.ts} +5 -2
  121. package/dist/redis-client.d.ts.map +1 -0
  122. package/dist/redis-client.js +98 -0
  123. package/dist/{api/reportError.d.ts → reportError.d.ts} +1 -1
  124. package/dist/reportError.d.ts.map +1 -0
  125. package/dist/reportError.js +28 -0
  126. package/dist/{api/routing → routing}/middleware/RouterMiddleware.d.ts +4 -3
  127. package/dist/routing/middleware/RouterMiddleware.d.ts.map +1 -0
  128. package/dist/{api/routing → routing}/middleware/RouterMiddleware.js +1 -1
  129. package/dist/routing/middleware/middleware.d.ts +48 -0
  130. package/dist/routing/middleware/middleware.d.ts.map +1 -0
  131. package/dist/routing/middleware/middleware.js +152 -0
  132. package/dist/{api/routing → routing}/middleware.d.ts +0 -1
  133. package/dist/routing/middleware.d.ts.map +1 -0
  134. package/dist/{api/routing → routing}/middleware.js +1 -2
  135. package/dist/routing/schema/jwt.d.ts.map +1 -0
  136. package/dist/routing/schema/jwt.js +13 -0
  137. package/dist/routing/tsort.d.ts.map +1 -0
  138. package/dist/routing/tsort.js +51 -0
  139. package/dist/{api/routing → routing}/utils.d.ts +3 -3
  140. package/dist/routing/utils.d.ts.map +1 -0
  141. package/dist/routing/utils.js +45 -0
  142. package/dist/routing.d.ts +182 -0
  143. package/dist/routing.d.ts.map +1 -0
  144. package/dist/routing.js +256 -0
  145. package/dist/test.d.ts +2 -2
  146. package/dist/test.d.ts.map +1 -1
  147. package/dist/test.js +2 -2
  148. package/dist/util.d.ts.map +1 -0
  149. package/dist/util.js +14 -0
  150. package/docs/cluster-storage.md +26 -0
  151. package/docs/workflow-engine.md +262 -0
  152. package/examples/query.ts +47 -39
  153. package/package.json +38 -352
  154. package/src/CUPS.ts +53 -14
  155. package/src/ClusterCosmos.ts +1118 -0
  156. package/src/ClusterServiceBus.ts +242 -0
  157. package/src/{api/ContextProvider.ts → ContextProvider.ts} +20 -17
  158. package/src/Emailer/Sendgrid.ts +83 -60
  159. package/src/Emailer/fake.ts +4 -4
  160. package/src/MainFiberSet.ts +32 -13
  161. package/src/QueueMaker/errors.ts +3 -1
  162. package/src/{adapters/SQL → SQL}/Model.ts +42 -41
  163. package/src/SQL.ts +1 -0
  164. package/src/Store/Cosmos/query.ts +218 -54
  165. package/src/Store/Cosmos.ts +529 -365
  166. package/src/Store/Disk.ts +112 -70
  167. package/src/Store/Memory.ts +365 -99
  168. package/src/Store/SQL/Pg.ts +389 -0
  169. package/src/Store/SQL/query.ts +603 -0
  170. package/src/Store/SQL.ts +766 -0
  171. package/src/Store/codeFilter.ts +8 -6
  172. package/src/Store/index.ts +25 -10
  173. package/src/Store/utils.ts +32 -25
  174. package/src/WorkflowEngineCosmos.ts +749 -0
  175. package/src/WorkflowEngineSqlite.ts +813 -0
  176. package/src/arbs.ts +5 -3
  177. package/src/{adapters/cosmos-client.ts → cosmos-client.ts} +5 -3
  178. package/src/errorReporter.ts +68 -78
  179. package/src/fileUtil.ts +1 -1
  180. package/src/index.ts +2 -1
  181. package/src/{api/internal → internal}/RequestContextMiddleware.ts +23 -6
  182. package/src/internal/auth.ts +272 -0
  183. package/src/{api/internal → internal}/events.ts +22 -13
  184. package/src/{api/layerUtils.ts → layerUtils.ts} +14 -10
  185. package/src/logger/jsonLogger.ts +5 -3
  186. package/src/logger/logFmtLogger.ts +3 -3
  187. package/src/logger/shared.ts +5 -4
  188. package/src/middlewares.ts +10 -0
  189. package/src/{adapters/mongo-client.ts → mongo-client.ts} +4 -2
  190. package/src/otel.ts +177 -0
  191. package/src/rateLimit.ts +34 -23
  192. package/src/{adapters/redis-client.ts → redis-client.ts} +7 -3
  193. package/src/{api/reportError.ts → reportError.ts} +3 -2
  194. package/src/{api/routing → routing}/middleware/RouterMiddleware.ts +5 -4
  195. package/src/routing/middleware/middleware.ts +196 -0
  196. package/src/routing/middleware.ts +4 -0
  197. package/src/{api/routing → routing}/schema/jwt.ts +2 -1
  198. package/src/{api/routing → routing}/utils.ts +2 -1
  199. package/src/routing.ts +823 -0
  200. package/src/test.ts +4 -4
  201. package/src/vitest.ts +1 -1
  202. package/test/auth.test.ts +101 -0
  203. package/test/cluster-cosmos.test.ts +612 -0
  204. package/test/cluster-servicebus.test.ts +180 -0
  205. package/test/cluster-sqlite.test.ts +205 -0
  206. package/test/contextProvider.test.ts +15 -12
  207. package/test/controller.test.ts +28 -32
  208. package/test/cosmos-query.test.ts +228 -0
  209. package/test/dist/auth.test.d.ts.map +1 -0
  210. package/test/dist/cluster-cosmos.test.d.ts.map +1 -0
  211. package/test/dist/cluster-servicebus.test.d.ts.map +1 -0
  212. package/test/dist/cluster-sqlite.test.d.ts.map +1 -0
  213. package/test/dist/contextProvider.test.d.ts.map +1 -1
  214. package/test/dist/controller.test.d.ts.map +1 -1
  215. package/test/dist/cosmos-query.test.d.ts.map +1 -0
  216. package/test/dist/fixtures.d.ts +29 -11
  217. package/test/dist/fixtures.d.ts.map +1 -1
  218. package/test/dist/fixtures.js +17 -10
  219. package/test/dist/query.test.d.ts.map +1 -1
  220. package/test/dist/rawQuery.test.d.ts.map +1 -1
  221. package/test/dist/repository-ext.test.d.ts.map +1 -0
  222. package/test/dist/requires.test.d.ts.map +1 -1
  223. package/test/dist/router-generator.test.d.ts.map +1 -0
  224. package/test/dist/routing-interruptibility.test.d.ts.map +1 -0
  225. package/test/dist/rpc-context-map-streaming.test.d.ts.map +1 -0
  226. package/test/dist/rpc-e2e-invalidation.test.d.ts.map +1 -0
  227. package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
  228. package/test/dist/rpc-stream-fullstack.test.d.ts.map +1 -0
  229. package/test/dist/sql-store.test.d.ts.map +1 -0
  230. package/test/dist/workflow-engine-cosmos.test.d.ts.map +1 -0
  231. package/test/dist/workflow-engine-sqlite.test.d.ts.map +1 -0
  232. package/test/fixtures.ts +16 -9
  233. package/test/layerUtils.test.ts +2 -2
  234. package/test/query.test.ts +1130 -41
  235. package/test/rawQuery.test.ts +340 -22
  236. package/test/repository-ext.test.ts +426 -0
  237. package/test/requires.test.ts +10 -5
  238. package/test/router-generator.test.ts +187 -0
  239. package/test/routing-interruptibility.test.ts +66 -0
  240. package/test/rpc-context-map-streaming.test.ts +262 -0
  241. package/test/rpc-e2e-invalidation.test.ts +418 -0
  242. package/test/rpc-multi-middleware.test.ts +85 -10
  243. package/test/rpc-stream-fullstack.test.ts +304 -0
  244. package/test/sql-store.test.ts +1711 -0
  245. package/test/validateSample.test.ts +26 -14
  246. package/test/workflow-engine-cosmos.test.ts +345 -0
  247. package/test/workflow-engine-sqlite.test.ts +297 -0
  248. package/tsconfig.examples.json +1 -1
  249. package/tsconfig.json +9 -2
  250. package/tsconfig.src.json +35 -35
  251. package/tsconfig.test.json +2 -2
  252. package/dist/Emailer/service.d.ts +0 -55
  253. package/dist/Emailer/service.d.ts.map +0 -1
  254. package/dist/Emailer/service.js +0 -6
  255. package/dist/Emailer.d.ts +0 -2
  256. package/dist/Emailer.d.ts.map +0 -1
  257. package/dist/Emailer.js +0 -2
  258. package/dist/Model/Repository/ext.d.ts +0 -41
  259. package/dist/Model/Repository/ext.d.ts.map +0 -1
  260. package/dist/Model/Repository/ext.js +0 -65
  261. package/dist/Model/Repository/internal/internal.d.ts +0 -59
  262. package/dist/Model/Repository/internal/internal.d.ts.map +0 -1
  263. package/dist/Model/Repository/internal/internal.js +0 -316
  264. package/dist/Model/Repository/legacy.d.ts +0 -19
  265. package/dist/Model/Repository/legacy.d.ts.map +0 -1
  266. package/dist/Model/Repository/legacy.js +0 -2
  267. package/dist/Model/Repository/makeRepo.d.ts +0 -49
  268. package/dist/Model/Repository/makeRepo.d.ts.map +0 -1
  269. package/dist/Model/Repository/makeRepo.js +0 -24
  270. package/dist/Model/Repository/service.d.ts +0 -89
  271. package/dist/Model/Repository/service.d.ts.map +0 -1
  272. package/dist/Model/Repository/service.js +0 -2
  273. package/dist/Model/Repository/validation.d.ts +0 -42
  274. package/dist/Model/Repository/validation.d.ts.map +0 -1
  275. package/dist/Model/Repository/validation.js +0 -32
  276. package/dist/Model/Repository.d.ts +0 -6
  277. package/dist/Model/Repository.d.ts.map +0 -1
  278. package/dist/Model/Repository.js +0 -6
  279. package/dist/Model/dsl.d.ts +0 -32
  280. package/dist/Model/dsl.d.ts.map +0 -1
  281. package/dist/Model/dsl.js +0 -44
  282. package/dist/Model/filter/filterApi.d.ts +0 -30
  283. package/dist/Model/filter/filterApi.d.ts.map +0 -1
  284. package/dist/Model/filter/filterApi.js +0 -2
  285. package/dist/Model/filter/types/errors.d.ts +0 -29
  286. package/dist/Model/filter/types/errors.d.ts.map +0 -1
  287. package/dist/Model/filter/types/errors.js +0 -2
  288. package/dist/Model/filter/types/fields.d.ts +0 -15
  289. package/dist/Model/filter/types/fields.d.ts.map +0 -1
  290. package/dist/Model/filter/types/fields.js +0 -2
  291. package/dist/Model/filter/types/path/common.d.ts +0 -316
  292. package/dist/Model/filter/types/path/common.d.ts.map +0 -1
  293. package/dist/Model/filter/types/path/common.js +0 -2
  294. package/dist/Model/filter/types/path/eager.d.ts +0 -95
  295. package/dist/Model/filter/types/path/eager.d.ts.map +0 -1
  296. package/dist/Model/filter/types/path/eager.js +0 -31
  297. package/dist/Model/filter/types/path/index.d.ts +0 -4
  298. package/dist/Model/filter/types/path/index.d.ts.map +0 -1
  299. package/dist/Model/filter/types/path/index.js +0 -3
  300. package/dist/Model/filter/types/utils.d.ts +0 -79
  301. package/dist/Model/filter/types/utils.d.ts.map +0 -1
  302. package/dist/Model/filter/types/utils.js +0 -2
  303. package/dist/Model/filter/types/validator.d.ts +0 -30
  304. package/dist/Model/filter/types/validator.d.ts.map +0 -1
  305. package/dist/Model/filter/types/validator.js +0 -2
  306. package/dist/Model/filter/types.d.ts +0 -5
  307. package/dist/Model/filter/types.d.ts.map +0 -1
  308. package/dist/Model/filter/types.js +0 -7
  309. package/dist/Model/query/dsl.d.ts +0 -248
  310. package/dist/Model/query/dsl.d.ts.map +0 -1
  311. package/dist/Model/query/dsl.js +0 -104
  312. package/dist/Model/query/new-kid-interpreter.d.ts +0 -28
  313. package/dist/Model/query/new-kid-interpreter.d.ts.map +0 -1
  314. package/dist/Model/query/new-kid-interpreter.js +0 -165
  315. package/dist/Model/query.d.ts +0 -15
  316. package/dist/Model/query.d.ts.map +0 -1
  317. package/dist/Model/query.js +0 -3
  318. package/dist/Model.d.ts +0 -4
  319. package/dist/Model.d.ts.map +0 -1
  320. package/dist/Model.js +0 -4
  321. package/dist/Operations.d.ts +0 -55
  322. package/dist/Operations.d.ts.map +0 -1
  323. package/dist/Operations.js +0 -102
  324. package/dist/OperationsRepo.d.ts +0 -41
  325. package/dist/OperationsRepo.d.ts.map +0 -1
  326. package/dist/OperationsRepo.js +0 -14
  327. package/dist/QueueMaker/SQLQueue.d.ts +0 -16
  328. package/dist/QueueMaker/SQLQueue.d.ts.map +0 -1
  329. package/dist/QueueMaker/SQLQueue.js +0 -130
  330. package/dist/QueueMaker/memQueue.d.ts +0 -11
  331. package/dist/QueueMaker/memQueue.d.ts.map +0 -1
  332. package/dist/QueueMaker/memQueue.js +0 -76
  333. package/dist/QueueMaker/sbqueue.d.ts +0 -12
  334. package/dist/QueueMaker/sbqueue.d.ts.map +0 -1
  335. package/dist/QueueMaker/sbqueue.js +0 -91
  336. package/dist/QueueMaker/service.d.ts +0 -11
  337. package/dist/QueueMaker/service.d.ts.map +0 -1
  338. package/dist/QueueMaker/service.js +0 -4
  339. package/dist/RequestContext.d.ts +0 -63
  340. package/dist/RequestContext.d.ts.map +0 -1
  341. package/dist/RequestContext.js +0 -49
  342. package/dist/RequestFiberSet.d.ts +0 -36
  343. package/dist/RequestFiberSet.d.ts.map +0 -1
  344. package/dist/RequestFiberSet.js +0 -78
  345. package/dist/Store/ContextMapContainer.d.ts +0 -14
  346. package/dist/Store/ContextMapContainer.d.ts.map +0 -1
  347. package/dist/Store/ContextMapContainer.js +0 -16
  348. package/dist/Store/service.d.ts +0 -108
  349. package/dist/Store/service.d.ts.map +0 -1
  350. package/dist/Store/service.js +0 -71
  351. package/dist/Store.d.ts +0 -2
  352. package/dist/Store.d.ts.map +0 -1
  353. package/dist/Store.js +0 -2
  354. package/dist/adapters/SQL/Model.d.ts.map +0 -1
  355. package/dist/adapters/SQL/Model.js +0 -478
  356. package/dist/adapters/SQL.d.ts.map +0 -1
  357. package/dist/adapters/ServiceBus.d.ts +0 -58
  358. package/dist/adapters/ServiceBus.d.ts.map +0 -1
  359. package/dist/adapters/ServiceBus.js +0 -99
  360. package/dist/adapters/cosmos-client.d.ts.map +0 -1
  361. package/dist/adapters/cosmos-client.js +0 -9
  362. package/dist/adapters/index.d.ts +0 -2
  363. package/dist/adapters/index.d.ts.map +0 -1
  364. package/dist/adapters/index.js +0 -2
  365. package/dist/adapters/logger.d.ts +0 -9
  366. package/dist/adapters/logger.d.ts.map +0 -1
  367. package/dist/adapters/logger.js +0 -3
  368. package/dist/adapters/memQueue.d.ts +0 -13
  369. package/dist/adapters/memQueue.d.ts.map +0 -1
  370. package/dist/adapters/memQueue.js +0 -20
  371. package/dist/adapters/mongo-client.d.ts.map +0 -1
  372. package/dist/adapters/mongo-client.js +0 -13
  373. package/dist/adapters/redis-client.d.ts.map +0 -1
  374. package/dist/adapters/redis-client.js +0 -94
  375. package/dist/api/ContextProvider.d.ts +0 -31
  376. package/dist/api/ContextProvider.d.ts.map +0 -1
  377. package/dist/api/ContextProvider.js +0 -38
  378. package/dist/api/codec.d.ts.map +0 -1
  379. package/dist/api/codec.js +0 -5
  380. package/dist/api/internal/RequestContextMiddleware.d.ts +0 -5
  381. package/dist/api/internal/RequestContextMiddleware.d.ts.map +0 -1
  382. package/dist/api/internal/RequestContextMiddleware.js +0 -35
  383. package/dist/api/internal/auth.d.ts +0 -15
  384. package/dist/api/internal/auth.d.ts.map +0 -1
  385. package/dist/api/internal/auth.js +0 -47
  386. package/dist/api/internal/events.d.ts +0 -9
  387. package/dist/api/internal/events.d.ts.map +0 -1
  388. package/dist/api/internal/events.js +0 -42
  389. package/dist/api/internal/health.d.ts.map +0 -1
  390. package/dist/api/internal/health.js +0 -5
  391. package/dist/api/layerUtils.d.ts.map +0 -1
  392. package/dist/api/layerUtils.js +0 -16
  393. package/dist/api/middlewares.d.ts.map +0 -1
  394. package/dist/api/reportError.d.ts.map +0 -1
  395. package/dist/api/reportError.js +0 -27
  396. package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +0 -1
  397. package/dist/api/routing/middleware/middleware.d.ts +0 -9
  398. package/dist/api/routing/middleware/middleware.d.ts.map +0 -1
  399. package/dist/api/routing/middleware/middleware.js +0 -92
  400. package/dist/api/routing/middleware.d.ts.map +0 -1
  401. package/dist/api/routing/schema/jwt.d.ts.map +0 -1
  402. package/dist/api/routing/schema/jwt.js +0 -12
  403. package/dist/api/routing/tsort.d.ts.map +0 -1
  404. package/dist/api/routing/tsort.js +0 -51
  405. package/dist/api/routing/utils.d.ts.map +0 -1
  406. package/dist/api/routing/utils.js +0 -44
  407. package/dist/api/routing.d.ts +0 -138
  408. package/dist/api/routing.d.ts.map +0 -1
  409. package/dist/api/routing.js +0 -166
  410. package/dist/api/setupRequest.d.ts +0 -12
  411. package/dist/api/setupRequest.d.ts.map +0 -1
  412. package/dist/api/setupRequest.js +0 -44
  413. package/dist/api/util.d.ts.map +0 -1
  414. package/dist/api/util.js +0 -14
  415. package/eslint.config.mjs +0 -24
  416. package/src/Emailer/service.ts +0 -52
  417. package/src/Emailer.ts +0 -1
  418. package/src/Model/Repository/ext.ts +0 -283
  419. package/src/Model/Repository/internal/internal.ts +0 -577
  420. package/src/Model/Repository/legacy.ts +0 -27
  421. package/src/Model/Repository/makeRepo.ts +0 -139
  422. package/src/Model/Repository/service.ts +0 -627
  423. package/src/Model/Repository/validation.ts +0 -31
  424. package/src/Model/Repository.ts +0 -5
  425. package/src/Model/dsl.ts +0 -128
  426. package/src/Model/filter/filterApi.ts +0 -60
  427. package/src/Model/filter/types/errors.ts +0 -47
  428. package/src/Model/filter/types/fields.ts +0 -50
  429. package/src/Model/filter/types/path/common.ts +0 -404
  430. package/src/Model/filter/types/path/eager.ts +0 -298
  431. package/src/Model/filter/types/path/index.ts +0 -4
  432. package/src/Model/filter/types/utils.ts +0 -128
  433. package/src/Model/filter/types/validator.ts +0 -46
  434. package/src/Model/filter/types.ts +0 -6
  435. package/src/Model/query/dsl.ts +0 -2110
  436. package/src/Model/query/new-kid-interpreter.ts +0 -210
  437. package/src/Model/query.ts +0 -13
  438. package/src/Model.ts +0 -3
  439. package/src/Operations.ts +0 -235
  440. package/src/OperationsRepo.ts +0 -16
  441. package/src/QueueMaker/SQLQueue.ts +0 -189
  442. package/src/QueueMaker/memQueue.ts +0 -130
  443. package/src/QueueMaker/sbqueue.ts +0 -137
  444. package/src/QueueMaker/service.ts +0 -17
  445. package/src/RequestContext.ts +0 -63
  446. package/src/RequestFiberSet.ts +0 -105
  447. package/src/Store/ContextMapContainer.ts +0 -20
  448. package/src/Store/index.test.ts.bak +0 -112
  449. package/src/Store/service.ts +0 -184
  450. package/src/Store.ts +0 -1
  451. package/src/adapters/SQL.ts +0 -1
  452. package/src/adapters/ServiceBus.ts +0 -209
  453. package/src/adapters/index.ts +0 -0
  454. package/src/adapters/logger.ts +0 -3
  455. package/src/adapters/memQueue.ts +0 -21
  456. package/src/api/internal/auth.ts +0 -68
  457. package/src/api/middlewares.ts +0 -10
  458. package/src/api/routing/middleware/middleware.ts +0 -128
  459. package/src/api/routing/middleware.ts +0 -6
  460. package/src/api/routing.ts +0 -598
  461. package/src/api/setupRequest.ts +0 -84
  462. package/tsconfig.json.bak +0 -12
  463. /package/dist/{adapters/SQL.d.ts → SQL.d.ts} +0 -0
  464. /package/dist/{api/codec.d.ts → codec.d.ts} +0 -0
  465. /package/dist/{api/internal → internal}/health.d.ts +0 -0
  466. /package/dist/{api/middlewares.d.ts → middlewares.d.ts} +0 -0
  467. /package/dist/{api/routing → routing}/schema/jwt.d.ts +0 -0
  468. /package/dist/{api/routing → routing}/tsort.d.ts +0 -0
  469. /package/dist/{api/util.d.ts → util.d.ts} +0 -0
  470. /package/src/{api/codec.ts → codec.ts} +0 -0
  471. /package/src/{api/internal → internal}/health.ts +0 -0
  472. /package/src/{api/routing → routing}/tsort.ts +0 -0
  473. /package/src/{api/util.ts → util.ts} +0 -0
@@ -0,0 +1,612 @@
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
+ const liveSnowflake = Layer.effect(Snowflake.Generator, TestClock.withLive(Snowflake.makeGenerator))
15
+
16
+ const layerFor = () =>
17
+ layerCosmos({
18
+ url: Redacted.make(cosmosUrl ?? ""),
19
+ dbName: cosmosDb,
20
+ prefix: "test-cluster-"
21
+ })
22
+ .pipe(
23
+ Layer.provideMerge(liveSnowflake),
24
+ Layer.provide(ShardingConfig.layerDefaults)
25
+ )
26
+
27
+ describe.skipIf(!cosmosUrl)("ClusterCosmos MessageStorage", () => {
28
+ it.effect("deduplicates keyed requests and returns the last reply", () =>
29
+ Effect
30
+ .gen(function*() {
31
+ const storage = yield* MessageStorage.MessageStorage
32
+ const shardId = testShardId("message-duplicate")
33
+ const primaryKey = `primary/${testRunId}\\with?illegal#chars`
34
+ const request = yield* makeStreamRequest(primaryKey, shardId)
35
+
36
+ const saved = yield* storage.saveRequest(request)
37
+ assert.strictEqual(saved._tag, "Success")
38
+
39
+ const chunk = yield* makeChunkReply(request, 0)
40
+ yield* storage.saveReply(chunk)
41
+
42
+ const duplicateWithChunk = yield* storage.saveRequest(
43
+ yield* makeStreamRequest(primaryKey, shardId)
44
+ )
45
+ assert(duplicateWithChunk._tag === "Duplicate" && Option.isSome(duplicateWithChunk.lastReceivedReply))
46
+ assert.strictEqual(duplicateWithChunk.lastReceivedReply.value._tag, "Chunk")
47
+
48
+ const ackChunk = yield* makeAckChunk(request, chunk)
49
+ yield* storage.saveEnvelope(ackChunk)
50
+ const repliesAfterAck = yield* storage.repliesFor([request])
51
+ assert.strictEqual(repliesAfterAck.length, 0)
52
+
53
+ yield* storage.saveReply(yield* makeStreamReply(request))
54
+ const duplicateWithExit = yield* storage.saveRequest(
55
+ yield* makeStreamRequest(primaryKey, shardId)
56
+ )
57
+ assert(duplicateWithExit._tag === "Duplicate" && Option.isSome(duplicateWithExit.lastReceivedReply))
58
+ assert.strictEqual(duplicateWithExit.lastReceivedReply.value._tag, "WithExit")
59
+ })
60
+ .pipe(Effect.provide(layerFor())))
61
+
62
+ it.effect("marks reads, resets shards, and excludes completed requests", () =>
63
+ Effect
64
+ .gen(function*() {
65
+ const storage = yield* MessageStorage.MessageStorage
66
+ const shardId = testShardId("message-unprocessed")
67
+ const request1 = yield* makeRequest({ payload: { id: 1 }, shardId })
68
+ const request2 = yield* makeRequest({ payload: { id: 2 }, shardId })
69
+ assert.strictEqual((yield* storage.saveRequest(request1))._tag, "Success")
70
+ assert.strictEqual((yield* storage.saveRequest(request2))._tag, "Success")
71
+
72
+ let messages = yield* storage.unprocessedMessages([request1.envelope.address.shardId])
73
+ assert.deepStrictEqual(messages.map((message) => requestPayloadId(message)).sort(), [1, 2])
74
+
75
+ messages = yield* storage.unprocessedMessages([request1.envelope.address.shardId])
76
+ assert.strictEqual(messages.length, 0)
77
+
78
+ yield* storage.resetShards([request1.envelope.address.shardId])
79
+ messages = yield* storage.unprocessedMessages([request1.envelope.address.shardId])
80
+ assert.deepStrictEqual(messages.map((message) => requestPayloadId(message)).sort(), [1, 2])
81
+
82
+ yield* storage.saveReply(yield* makeReply(request1))
83
+ yield* storage.resetShards([request1.envelope.address.shardId])
84
+ messages = yield* storage.unprocessedMessages([request1.envelope.address.shardId])
85
+ assert.deepStrictEqual(messages.map((message) => requestPayloadId(message)), [2])
86
+ })
87
+ .pipe(Effect.provide(layerFor())))
88
+
89
+ it.effect("returns each unprocessed message to only one concurrent node poll", () =>
90
+ Effect
91
+ .gen(function*() {
92
+ const storage = yield* MessageStorage.MessageStorage
93
+ const shardId = testShardId("message-concurrent-poll")
94
+ const expectedIds = Array.from({ length: 20 }, (_, index) => index + 1)
95
+ const requests = yield* Effect.forEach(expectedIds, (id) => makeRequest({ payload: { id }, shardId }))
96
+ yield* Effect.forEach(requests, (request) => storage.saveRequest(request), { discard: true })
97
+
98
+ const polls = yield* Effect.forEach(
99
+ Array.from({ length: 8 }, () => void 0),
100
+ () => storage.unprocessedMessages([shardId]),
101
+ { concurrency: "unbounded" }
102
+ )
103
+ const receivedIds = polls
104
+ .flatMap((messages) => messages.map(requestPayloadId))
105
+ .sort((a, b) => a - b)
106
+
107
+ assert.deepStrictEqual(receivedIds, expectedIds)
108
+ assert.strictEqual((yield* storage.unprocessedMessages([shardId])).length, 0)
109
+ })
110
+ .pipe(Effect.provide(layerFor())), 20000)
111
+
112
+ it.effect("preserves terminal reply state after concurrent node polling", () =>
113
+ Effect
114
+ .gen(function*() {
115
+ const storage = yield* MessageStorage.MessageStorage
116
+ const shardId = testShardId("message-concurrent-reply")
117
+ const primaryKey = `concurrent-reply/${testRunId}`
118
+ const request = yield* makeStreamRequest(primaryKey, shardId)
119
+ assert.strictEqual((yield* storage.saveRequest(request))._tag, "Success")
120
+
121
+ const polls = yield* Effect.forEach(
122
+ Array.from({ length: 8 }, () => void 0),
123
+ () => storage.unprocessedMessages([shardId]),
124
+ { concurrency: "unbounded" }
125
+ )
126
+ assert.strictEqual(polls.flat().length, 1)
127
+
128
+ yield* storage.saveReply(yield* makeStreamReply(request))
129
+
130
+ const duplicate = yield* storage.saveRequest(yield* makeStreamRequest(primaryKey, shardId))
131
+ assert(duplicate._tag === "Duplicate" && Option.isSome(duplicate.lastReceivedReply))
132
+ assert.strictEqual(duplicate.lastReceivedReply.value._tag, "WithExit")
133
+ })
134
+ .pipe(Effect.provide(layerFor())), 20000)
135
+
136
+ it.effect("notifies registered reply handlers", () =>
137
+ Effect
138
+ .gen(function*() {
139
+ const storage = yield* MessageStorage.MessageStorage
140
+ const latch = yield* Latch.make()
141
+ const request = yield* makeRequest({ shardId: testShardId("message-handler") })
142
+ yield* storage.saveRequest(request)
143
+
144
+ const fiber = yield* storage
145
+ .registerReplyHandler(
146
+ new Message.OutgoingRequest({
147
+ ...request,
148
+ respond: () => latch.open
149
+ })
150
+ )
151
+ .pipe(Effect.forkChild)
152
+
153
+ yield* TestClock.adjust(1)
154
+ yield* storage.saveReply(yield* makeReply(request))
155
+ yield* latch.await
156
+ yield* Fiber.await(fiber)
157
+ })
158
+ .pipe(Effect.provide(layerFor())))
159
+ })
160
+
161
+ describe.skipIf(!cosmosUrl)("ClusterCosmos RunnerStorage", () => {
162
+ it.effect("registers runners and tracks health", () =>
163
+ Effect
164
+ .gen(function*() {
165
+ const storage = yield* RunnerStorage.RunnerStorage
166
+ const runnerAddress = testRunnerAddress(1)
167
+ const runner = Runner.make({
168
+ address: runnerAddress,
169
+ groups: ["default"],
170
+ weight: 1
171
+ })
172
+
173
+ const machineId1 = yield* storage.register(runner, true)
174
+ const machineId2 = yield* storage.register(runner, true)
175
+ assert.deepStrictEqual(machineId2, machineId1)
176
+ expect(runnerStatus(yield* storage.getRunners, runnerAddress)).toEqual([runner, true])
177
+
178
+ yield* storage.setRunnerHealth(runnerAddress, false)
179
+ expect(runnerStatus(yield* storage.getRunners, runnerAddress)).toEqual([runner, false])
180
+
181
+ yield* storage.unregister(runnerAddress)
182
+ expect(runnerStatus(yield* storage.getRunners, runnerAddress)).toBeUndefined()
183
+ })
184
+ .pipe(Effect.provide(layerFor())))
185
+
186
+ it.effect("allocates distinct machine ids for distinct runners", () =>
187
+ Effect
188
+ .gen(function*() {
189
+ const storage = yield* RunnerStorage.RunnerStorage
190
+ const address1 = testRunnerAddress(6)
191
+ const address2 = testRunnerAddress(7)
192
+ const runner1 = Runner.make({ address: address1, groups: ["default"], weight: 1 })
193
+ const runner2 = Runner.make({ address: address2, groups: ["default"], weight: 1 })
194
+
195
+ const id1 = yield* storage.register(runner1, true)
196
+ const id2 = yield* storage.register(runner2, true)
197
+ // Distinct runners must get distinct machine ids (would otherwise risk
198
+ // colliding Snowflake ids).
199
+ assert(id1 !== id2)
200
+ // Re-registration is stable per address.
201
+ assert.deepStrictEqual(yield* storage.register(runner1, true), id1)
202
+
203
+ yield* storage.unregister(address1)
204
+ yield* storage.unregister(address2)
205
+ })
206
+ .pipe(Effect.provide(layerFor())))
207
+
208
+ it.effect("preserves shard lock ownership when two runners acquire concurrently", () =>
209
+ Effect
210
+ .gen(function*() {
211
+ const storage = yield* RunnerStorage.RunnerStorage
212
+ const runnerAddress1 = testRunnerAddress(4)
213
+ const runnerAddress2 = testRunnerAddress(5)
214
+ const runner1 = Runner.make({
215
+ address: runnerAddress1,
216
+ groups: ["default"],
217
+ weight: 1
218
+ })
219
+ const runner2 = Runner.make({
220
+ address: runnerAddress2,
221
+ groups: ["default"],
222
+ weight: 1
223
+ })
224
+ const shards = Array.from({ length: 16 }, (_, index) => testShardId("runner-occ", index + 1))
225
+
226
+ yield* storage.register(runner1, true)
227
+ yield* storage.register(runner2, true)
228
+
229
+ const [acquired1, acquired2] = yield* Effect.all([
230
+ storage.acquire(runnerAddress1, shards),
231
+ storage.acquire(runnerAddress2, shards)
232
+ ], { concurrency: "unbounded" })
233
+ const acquiredIds = [...acquired1, ...acquired2].map((shard) => shard.id).sort((a, b) => a - b)
234
+
235
+ assert.deepStrictEqual(acquiredIds, shards.map((shard) => shard.id))
236
+ assert.strictEqual(new Set(acquiredIds).size, shards.length)
237
+ assert.deepStrictEqual(
238
+ (yield* storage.refresh(runnerAddress1, shards)).map((shard) => shard.id).sort((a, b) => a - b),
239
+ acquired1.map((shard) => shard.id).sort((a, b) => a - b)
240
+ )
241
+ assert.deepStrictEqual(
242
+ (yield* storage.refresh(runnerAddress2, shards)).map((shard) => shard.id).sort((a, b) => a - b),
243
+ acquired2.map((shard) => shard.id).sort((a, b) => a - b)
244
+ )
245
+ })
246
+ .pipe(Effect.provide(layerFor())), 20000)
247
+
248
+ it.effect("acquires, refreshes, releases, and re-acquires shard locks", () =>
249
+ Effect
250
+ .gen(function*() {
251
+ const storage = yield* RunnerStorage.RunnerStorage
252
+ const runnerAddress1 = testRunnerAddress(2)
253
+ const runnerAddress2 = testRunnerAddress(3)
254
+ const shards = [
255
+ testShardId("runner-locks", 1),
256
+ testShardId("runner-locks", 2),
257
+ testShardId("runner-locks", 3)
258
+ ]
259
+
260
+ let acquired = yield* storage.acquire(runnerAddress1, shards)
261
+ assert.deepStrictEqual(acquired.map((shard) => shard.id), [1, 2, 3])
262
+
263
+ acquired = yield* storage.acquire(runnerAddress2, shards)
264
+ assert.deepStrictEqual(acquired.map((shard) => shard.id), [])
265
+
266
+ const refreshed = yield* storage.refresh(runnerAddress1, shards)
267
+ assert.deepStrictEqual(refreshed.map((shard) => shard.id), [1, 2, 3])
268
+
269
+ yield* storage.release(runnerAddress1, testShardId("runner-locks", 2))
270
+ acquired = yield* storage.acquire(runnerAddress2, shards)
271
+ assert.deepStrictEqual(acquired.map((shard) => shard.id), [2])
272
+
273
+ yield* storage.releaseAll(runnerAddress1)
274
+ acquired = yield* storage.acquire(runnerAddress2, shards)
275
+ assert.deepStrictEqual(acquired.map((shard) => shard.id), [1, 2, 3])
276
+ })
277
+ .pipe(Effect.provide(layerFor())))
278
+ })
279
+
280
+ describe.skipIf(!cosmosUrl)("ClusterCosmos Sharding RPC", () => {
281
+ it.effect("runs persisted entity RPCs through Cosmos-backed cluster storage", () =>
282
+ Effect
283
+ .gen(function*() {
284
+ yield* TestClock.adjust(1)
285
+ const sharding = yield* Sharding.Sharding
286
+ const makeClient = yield* CosmosRpcEntity.client
287
+ const entityId = `entity/${testRunId}\\with?illegal#chars`
288
+ const shardId = sharding.getShardId(EntityId.make(entityId), testShardGroup("rpc"))
289
+ yield* waitForShard(sharding, shardId)
290
+ assert.isTrue(sharding.hasShardId(shardId))
291
+ const client = makeClient(entityId)
292
+
293
+ const user = yield* client.GetCosmosUser({ id: 42 })
294
+ expect(user).toEqual(new CosmosRpcUser({ id: 42, name: "User 42" }))
295
+
296
+ const primaryKey = `rpc/${testRunId}\\with?illegal#chars`
297
+ const first = yield* client.CosmosRequestWithKey({ key: primaryKey })
298
+ const duplicate = yield* client.CosmosRequestWithKey({ key: primaryKey })
299
+
300
+ assert.strictEqual(first, primaryKey)
301
+ assert.strictEqual(duplicate, primaryKey)
302
+ })
303
+ .pipe(Effect.provide(clusterRpcLayer("rpc"))), 20000)
304
+ })
305
+
306
+ describe.skipIf(!cosmosUrl)("ClusterCosmos Workflow", () => {
307
+ it.live("resumes a running workflow suspended on a durable deferred", () =>
308
+ Effect
309
+ .gen(function*() {
310
+ const sharding = yield* Sharding.Sharding
311
+ const payload = { id: `deferred/${testRunId}\\with?illegal#chars` }
312
+ const executionId = yield* CosmosDeferredWorkflow.executionId(payload)
313
+
314
+ const fiber = yield* CosmosDeferredWorkflow.execute(payload).pipe(Effect.forkScoped)
315
+ yield* waitForDeferredWorkflowSuspended(executionId)
316
+
317
+ const token = yield* DurableDeferred.tokenFromPayload(CosmosDeferred, {
318
+ workflow: CosmosDeferredWorkflow,
319
+ payload
320
+ })
321
+ yield* DurableDeferred.done(CosmosDeferred, { token, exit: Exit.succeed("resolved") })
322
+ yield* sharding.pollStorage
323
+
324
+ const value = yield* Fiber.join(fiber).pipe(Effect.timeout(Duration.seconds(15)))
325
+ assert.strictEqual(value, `${payload.id}:resolved`)
326
+ assert.strictEqual(yield* waitForDeferredWorkflowComplete(executionId), `${payload.id}:resolved`)
327
+ })
328
+ .pipe(Effect.provide(clusterWorkflowLayer())), 30000)
329
+ })
330
+
331
+ const GetUserRpc = Rpc.make("GetUser", {
332
+ payload: { id: Schema.Number }
333
+ })
334
+
335
+ class CosmosRpcUser extends Schema.Class<CosmosRpcUser>("CosmosRpcUser")({
336
+ id: Schema.Number,
337
+ name: Schema.String
338
+ }) {}
339
+
340
+ const CosmosRpcEntity = Entity
341
+ .make("CosmosRpcEntity", [
342
+ Rpc.make("GetCosmosUser", {
343
+ success: CosmosRpcUser,
344
+ payload: { id: Schema.Number }
345
+ }),
346
+ Rpc.make("CosmosRequestWithKey", {
347
+ success: Schema.String,
348
+ payload: { key: Schema.String },
349
+ primaryKey: ({ key }) => key
350
+ })
351
+ ])
352
+ .annotate(ClusterSchema.ShardGroup, () => testShardGroup("rpc"))
353
+ .annotateRpcs(ClusterSchema.Persisted, true)
354
+
355
+ const CosmosRpcEntityLayer = CosmosRpcEntity.toLayer(
356
+ Effect.succeed(
357
+ CosmosRpcEntity.of({
358
+ GetCosmosUser: (envelope) =>
359
+ Effect.succeed(new CosmosRpcUser({ id: envelope.payload.id, name: `User ${envelope.payload.id}` })),
360
+ CosmosRequestWithKey: (envelope) => Effect.succeed(envelope.payload.key)
361
+ })
362
+ )
363
+ )
364
+
365
+ const CosmosDeferred = DurableDeferred.make("ClusterCosmos/Deferred", { success: Schema.String })
366
+
367
+ const CosmosDeferredWorkflow = Workflow
368
+ .make("ClusterCosmos/DeferredWorkflow", {
369
+ payload: { id: Schema.String },
370
+ success: Schema.String,
371
+ idempotencyKey: ({ id }) => id
372
+ })
373
+ .annotate(ClusterSchema.ShardGroup, () => testShardGroup("workflow"))
374
+
375
+ const CosmosDeferredWorkflowLayer = CosmosDeferredWorkflow.toLayer(Effect.fnUntraced(function*({ id }) {
376
+ const value = yield* DurableDeferred.await(CosmosDeferred)
377
+ return `${id}:${value}`
378
+ }))
379
+
380
+ class StreamRpc extends Rpc.make("StreamTest", {
381
+ success: RpcSchema.Stream(Schema.Void, Schema.Never),
382
+ payload: {
383
+ id: Schema.String
384
+ },
385
+ primaryKey: (value) => value.id.toString()
386
+ }) {}
387
+
388
+ const makeRequest = Effect.fnUntraced(function*(options?: {
389
+ readonly payload?: { readonly id: number }
390
+ readonly shardId?: ShardId.ShardId
391
+ }) {
392
+ const snowflake = yield* Snowflake.Generator
393
+ return new Message.OutgoingRequest({
394
+ envelope: Envelope.makeRequest<typeof GetUserRpc>({
395
+ requestId: snowflake.nextUnsafe(),
396
+ address: EntityAddress.make({
397
+ shardId: options?.shardId ?? testShardId("default"),
398
+ entityType: EntityType.make("test"),
399
+ entityId: EntityId.make("1")
400
+ }),
401
+ tag: GetUserRpc._tag,
402
+ payload: options?.payload ?? { id: 123 },
403
+ traceId: "noop",
404
+ spanId: "noop",
405
+ sampled: false,
406
+ headers: Headers.empty
407
+ }),
408
+ annotations: GetUserRpc.annotations,
409
+ context: Context.empty(),
410
+ rpc: GetUserRpc,
411
+ lastReceivedReply: Option.none(),
412
+ respond() {
413
+ return Effect.void
414
+ }
415
+ })
416
+ })
417
+
418
+ const makeStreamRequest = Effect.fnUntraced(function*(id: string, shardId = testShardId("stream")) {
419
+ const snowflake = yield* Snowflake.Generator
420
+ return new Message.OutgoingRequest({
421
+ envelope: Envelope.makeRequest<typeof StreamRpc>({
422
+ requestId: snowflake.nextUnsafe(),
423
+ address: EntityAddress.make({
424
+ shardId,
425
+ entityType: EntityType.make("test"),
426
+ entityId: EntityId.make("1")
427
+ }),
428
+ tag: StreamRpc._tag,
429
+ payload: StreamRpc.payloadSchema.make({ id }),
430
+ traceId: "noop",
431
+ spanId: "noop",
432
+ sampled: false,
433
+ headers: Headers.empty
434
+ }),
435
+ annotations: StreamRpc.annotations,
436
+ context: Context.empty(),
437
+ rpc: StreamRpc,
438
+ lastReceivedReply: Option.none(),
439
+ respond() {
440
+ return Effect.void
441
+ }
442
+ })
443
+ })
444
+
445
+ const makeReply = Effect.fnUntraced(function*(request: Message.OutgoingRequest<typeof GetUserRpc>) {
446
+ const snowflake = yield* Snowflake.Generator
447
+ return new Reply.ReplyWithContext({
448
+ reply: new Reply.WithExit<typeof GetUserRpc>({
449
+ id: snowflake.nextUnsafe(),
450
+ requestId: request.envelope.requestId,
451
+ exit: Exit.void
452
+ }),
453
+ context: request.context,
454
+ rpc: request.rpc
455
+ })
456
+ })
457
+
458
+ const makeStreamReply = Effect.fnUntraced(function*(request: Message.OutgoingRequest<typeof StreamRpc>) {
459
+ const snowflake = yield* Snowflake.Generator
460
+ return new Reply.ReplyWithContext({
461
+ reply: new Reply.WithExit<typeof StreamRpc>({
462
+ id: snowflake.nextUnsafe(),
463
+ requestId: request.envelope.requestId,
464
+ exit: Exit.void
465
+ }),
466
+ context: request.context,
467
+ rpc: request.rpc
468
+ })
469
+ })
470
+
471
+ const makeAckChunk = Effect.fnUntraced(function*(
472
+ request: Message.OutgoingRequest<typeof StreamRpc>,
473
+ chunk: Reply.ReplyWithContext<typeof StreamRpc>
474
+ ) {
475
+ const snowflake = yield* Snowflake.Generator
476
+ return new Message.OutgoingEnvelope({
477
+ envelope: new Envelope.AckChunk({
478
+ id: snowflake.nextUnsafe(),
479
+ address: request.envelope.address,
480
+ requestId: chunk.reply.requestId,
481
+ replyId: chunk.reply.id
482
+ }),
483
+ rpc: request.rpc
484
+ })
485
+ })
486
+
487
+ const makeChunkReply = Effect.fnUntraced(function*(
488
+ request: Message.OutgoingRequest<typeof StreamRpc>,
489
+ sequence: number
490
+ ) {
491
+ const snowflake = yield* Snowflake.Generator
492
+ return new Reply.ReplyWithContext({
493
+ reply: new Reply.Chunk<typeof StreamRpc>({
494
+ id: snowflake.nextUnsafe(),
495
+ requestId: request.envelope.requestId,
496
+ sequence,
497
+ values: [undefined]
498
+ }),
499
+ context: request.context,
500
+ rpc: request.rpc
501
+ })
502
+ })
503
+
504
+ const requestPayloadId = (message: Message.Incoming<never>) => {
505
+ if (message.envelope._tag !== "Request") {
506
+ throw new Error(`Expected Request envelope`)
507
+ }
508
+ const envelope = message.envelope
509
+ assert(typeof envelope.payload === "object" && envelope.payload !== null)
510
+ assert("id" in envelope.payload)
511
+ assert.strictEqual(typeof envelope.payload.id, "number")
512
+ return envelope.payload.id
513
+ }
514
+
515
+ const testShardId = (label: string, id = 1) => ShardId.make(`cluster-cosmos-${testRunId}-${label}`, id)
516
+
517
+ const testShardGroup = (label: string) => `cluster-cosmos-${testRunId}-${label}`
518
+
519
+ const testRunnerAddress = (offset: number) => RunnerAddress.make("localhost", runnerPortBase + offset)
520
+
521
+ const runnerStatus = (
522
+ runners: ReadonlyArray<readonly [Runner.Runner, boolean]>,
523
+ address: RunnerAddress.RunnerAddress
524
+ ) => runners.find(([runner]) => runner.address.host === address.host && runner.address.port === address.port)
525
+
526
+ const clusterRpcLayer = (label: string) => {
527
+ const shardGroup = testShardGroup(label)
528
+ return CosmosRpcEntityLayer.pipe(
529
+ Layer.provideMerge(Sharding.layer),
530
+ Layer.provide(Runners.layerNoop),
531
+ Layer.provide(RunnerHealth.layerNoop),
532
+ Layer.provide(layerCosmos({
533
+ url: Redacted.make(cosmosUrl ?? ""),
534
+ dbName: cosmosDb,
535
+ prefix: "test-cluster-"
536
+ })),
537
+ Layer.provide(ShardingConfig.layer({
538
+ runnerAddress: Option.some(testRunnerAddress(10)),
539
+ shardsPerGroup: 1,
540
+ availableShardGroups: [shardGroup],
541
+ assignedShardGroups: [shardGroup],
542
+ entityTerminationTimeout: 0,
543
+ entityMessagePollInterval: 50,
544
+ entityReplyPollInterval: 50,
545
+ refreshAssignmentsInterval: 0,
546
+ sendRetryInterval: 50
547
+ }))
548
+ )
549
+ }
550
+
551
+ const clusterWorkflowLayer = () =>
552
+ CosmosDeferredWorkflowLayer.pipe(
553
+ Layer.provideMerge(
554
+ ClusterWorkflowEngine.layer.pipe(
555
+ Layer.provideMerge(Sharding.layer),
556
+ Layer.provide(Runners.layerNoop),
557
+ Layer.provide(RunnerHealth.layerNoop),
558
+ Layer.provide(layerCosmos({
559
+ url: Redacted.make(cosmosUrl ?? ""),
560
+ dbName: cosmosDb,
561
+ prefix: "test-cluster-"
562
+ })),
563
+ Layer.provide(ShardingConfig.layer({
564
+ runnerAddress: Option.some(testRunnerAddress(20)),
565
+ shardsPerGroup: 1,
566
+ availableShardGroups: [testShardGroup("workflow")],
567
+ assignedShardGroups: [testShardGroup("workflow")],
568
+ entityTerminationTimeout: 0,
569
+ entityMessagePollInterval: 50,
570
+ entityReplyPollInterval: 50,
571
+ refreshAssignmentsInterval: 0,
572
+ sendRetryInterval: 50
573
+ }))
574
+ )
575
+ )
576
+ )
577
+
578
+ const waitForDeferredWorkflowSuspended = (executionId: string) =>
579
+ Effect.gen(function*() {
580
+ const sharding = yield* Sharding.Sharding
581
+ for (let i = 0; i < 100; i++) {
582
+ yield* sharding.pollStorage
583
+ const polled = yield* CosmosDeferredWorkflow.poll(executionId)
584
+ if (Option.isSome(polled) && polled.value._tag === "Suspended") return
585
+ yield* Effect.sleep(Duration.millis(100))
586
+ }
587
+ return yield* Effect.fail(new Error(`Workflow ${executionId} did not suspend`))
588
+ })
589
+
590
+ const waitForDeferredWorkflowComplete = (executionId: string) =>
591
+ Effect.gen(function*() {
592
+ const sharding = yield* Sharding.Sharding
593
+ for (let i = 0; i < 100; i++) {
594
+ yield* sharding.pollStorage
595
+ const polled = yield* CosmosDeferredWorkflow.poll(executionId)
596
+ if (Option.isSome(polled) && polled.value._tag === "Complete") {
597
+ const exit = polled.value.exit
598
+ assert(Exit.isSuccess(exit))
599
+ return exit.value
600
+ }
601
+ yield* Effect.sleep(Duration.millis(100))
602
+ }
603
+ return yield* Effect.fail(new Error(`Workflow ${executionId} did not complete`))
604
+ })
605
+
606
+ const waitForShard = (sharding: Sharding.Sharding["Service"], shardId: ShardId.ShardId) =>
607
+ Effect.gen(function*() {
608
+ for (let i = 0; i < 30; i++) {
609
+ if (sharding.hasShardId(shardId)) return
610
+ yield* Effect.promise<void>(() => new Promise((resolve) => setTimeout(resolve, 100)))
611
+ }
612
+ })