@effect-app/infra 4.0.0-beta.98 → 4.0.0

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