@effect-app/infra 0.7.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 (438) hide show
  1. package/.eslintrc.cjs +11 -0
  2. package/.jest-cache/haste-map-369fa5ca2164cc35b19159bd76147276-e7a7ff05756c055cb63be97ba8537525-314902b6271c341511f7398a50469024 +0 -0
  3. package/.jest-cache/haste-map-369fa5ca2164cc35b19159bd76147276-e7a7ff05756c055cb63be97ba8537525-3f072cc7afa09b6adaead0527ab9df83 +0 -0
  4. package/.jest-cache/haste-map-369fa5ca2164cc35b19159bd76147276-e7a7ff05756c055cb63be97ba8537525-74c3c295c110fc861b6a4c673afc3e24 +0 -0
  5. package/.jest-cache/haste-map-369fa5ca2164cc35b19159bd76147276-e7a7ff05756c055cb63be97ba8537525-bf6dae8cb9ea9740ceb39aefaf12716c +0 -0
  6. package/.jest-cache/haste-map-369fa5ca2164cc35b19159bd76147276-e7a7ff05756c055cb63be97ba8537525-cf9d1486029526079a5f68f2041dea02 +0 -0
  7. package/.jest-cache/haste-map-4ca41cc04e60c616a19cbb483cbf487b-e2f1f4b6d87214e3c49442fed31f310c-b4710ed9fb3d0757c4bf23045c585670 +0 -0
  8. package/.jest-cache/haste-map-4ca41cc04e60c616a19cbb483cbf487b-e2f1f4b6d87214e3c49442fed31f310c-ee17e5395bb1b7b36a4e2e22a6ae1449 +0 -0
  9. package/.jest-cache/haste-map-7dc16d7fae8c072843ed1c69eae73100-a8a4225b317477b49bca31f54559afb3-c16136699bb7f463be85273162b447c3 +0 -0
  10. package/.jest-cache/haste-map-9aa1e395a82e108eb49698982c574272-e2f1f4b6d87214e3c49442fed31f310c-f7435f46fc41ac5a13d06a49cae9a650 +0 -0
  11. package/.jest-cache/haste-map-9d206b45d610536c9ec65eec263c6964-a8a4225b317477b49bca31f54559afb3-3510506a330b44f1ae629033aac8fbb3 +0 -0
  12. package/.jest-cache/haste-map-a00ab30d0d656f9d3990958a54b9ccfd-87603b0fc921b26b622a5859b4c92bed-17b550b450b18840c25861aa6e835f0c +0 -0
  13. package/.jest-cache/haste-map-a00ab30d0d656f9d3990958a54b9ccfd-87603b0fc921b26b622a5859b4c92bed-4dc31290b1efc98335eb4c89167d75c3 +0 -0
  14. package/.jest-cache/haste-map-ab843cb0ffbadfd0deea4adb182c7ecd-87603b0fc921b26b622a5859b4c92bed-997106edf4bbc31567a378146180e45e +0 -0
  15. package/.jest-cache/haste-map-ab843cb0ffbadfd0deea4adb182c7ecd-87603b0fc921b26b622a5859b4c92bed-f0cd25414f9ed16c446940ca3aa23c1b +0 -0
  16. package/.jest-cache/haste-map-cf17f2edf0e949eebfdfca561816457c-e7a7ff05756c055cb63be97ba8537525-2cac07d09e6384e2d37c49714edad0ba +0 -0
  17. package/.jest-cache/haste-map-cf17f2edf0e949eebfdfca561816457c-e7a7ff05756c055cb63be97ba8537525-d7967c2976c5feac7161c964f0aa442f +0 -0
  18. package/.jest-cache/haste-map-fb1a173276d25bbff02f815600059283-938122bdc1c8836874b6585d7acb2e99-f705929cca05ce95ceaa6d520b560ce8 +0 -0
  19. package/.prettierignore +6 -0
  20. package/_cjs/_global.cjs +6 -0
  21. package/_cjs/_global.cjs.map +1 -0
  22. package/_cjs/_global.ext.cjs +6 -0
  23. package/_cjs/_global.ext.cjs.map +1 -0
  24. package/_cjs/_global.schema.cjs +5 -0
  25. package/_cjs/_global.schema.cjs.map +1 -0
  26. package/_cjs/errors.cjs +82 -0
  27. package/_cjs/errors.cjs.map +1 -0
  28. package/_cjs/ext.cjs +4 -0
  29. package/_cjs/ext.cjs.map +1 -0
  30. package/_cjs/index.cjs +6 -0
  31. package/_cjs/index.cjs.map +1 -0
  32. package/_cjs/lib/RequestContext.cjs +70 -0
  33. package/_cjs/lib/RequestContext.cjs.map +1 -0
  34. package/_cjs/lib/api/authorization.jwt.cjs +44 -0
  35. package/_cjs/lib/api/authorization.jwt.cjs.map +1 -0
  36. package/_cjs/lib/api/defaultErrorHandler.cjs +45 -0
  37. package/_cjs/lib/api/defaultErrorHandler.cjs.map +1 -0
  38. package/_cjs/lib/api/reportError.cjs +64 -0
  39. package/_cjs/lib/api/reportError.cjs.map +1 -0
  40. package/_cjs/lib/api/routing.cjs +262 -0
  41. package/_cjs/lib/api/routing.cjs.map +1 -0
  42. package/_cjs/lib/api/setupRequest.cjs +35 -0
  43. package/_cjs/lib/api/setupRequest.cjs.map +1 -0
  44. package/_cjs/lib/api/util.cjs +17 -0
  45. package/_cjs/lib/api/util.cjs.map +1 -0
  46. package/_cjs/lib/api/writeDocs.cjs +31 -0
  47. package/_cjs/lib/api/writeDocs.cjs.map +1 -0
  48. package/_cjs/lib/errorReporter.cjs +72 -0
  49. package/_cjs/lib/errorReporter.cjs.map +1 -0
  50. package/_cjs/lib/ext/Array.cjs +30 -0
  51. package/_cjs/lib/ext/Array.cjs.map +1 -0
  52. package/_cjs/lib/fileUtil.cjs +36 -0
  53. package/_cjs/lib/fileUtil.cjs.map +1 -0
  54. package/_cjs/lib/filter/types/errors.cjs +6 -0
  55. package/_cjs/lib/filter/types/errors.cjs.map +1 -0
  56. package/_cjs/lib/filter/types/fields.cjs +6 -0
  57. package/_cjs/lib/filter/types/fields.cjs.map +1 -0
  58. package/_cjs/lib/filter/types/index.cjs +61 -0
  59. package/_cjs/lib/filter/types/index.cjs.map +1 -0
  60. package/_cjs/lib/filter/types/path/common.cjs +6 -0
  61. package/_cjs/lib/filter/types/path/common.cjs.map +1 -0
  62. package/_cjs/lib/filter/types/path/eager.cjs +6 -0
  63. package/_cjs/lib/filter/types/path/eager.cjs.map +1 -0
  64. package/_cjs/lib/filter/types/path/index.cjs +8 -0
  65. package/_cjs/lib/filter/types/path/index.cjs.map +1 -0
  66. package/_cjs/lib/filter/types/utils.cjs +6 -0
  67. package/_cjs/lib/filter/types/utils.cjs.map +1 -0
  68. package/_cjs/lib/filter/types/validator.cjs +6 -0
  69. package/_cjs/lib/filter/types/validator.cjs.map +1 -0
  70. package/_cjs/lib/filter.cjs +238 -0
  71. package/_cjs/lib/filter.cjs.map +1 -0
  72. package/_cjs/lib/instrument.cjs +20 -0
  73. package/_cjs/lib/instrument.cjs.map +1 -0
  74. package/_cjs/lib/rateLimit.cjs +88 -0
  75. package/_cjs/lib/rateLimit.cjs.map +1 -0
  76. package/_cjs/services/CUPS/service.cjs +15 -0
  77. package/_cjs/services/CUPS/service.cjs.map +1 -0
  78. package/_cjs/services/CUPS.cjs +113 -0
  79. package/_cjs/services/CUPS.cjs.map +1 -0
  80. package/_cjs/services/Cache.cjs +39 -0
  81. package/_cjs/services/Cache.cjs.map +1 -0
  82. package/_cjs/services/Emailer/Sendgrid.cjs +112 -0
  83. package/_cjs/services/Emailer/Sendgrid.cjs.map +1 -0
  84. package/_cjs/services/Emailer/fake.cjs +24 -0
  85. package/_cjs/services/Emailer/fake.cjs.map +1 -0
  86. package/_cjs/services/Emailer/service.cjs +12 -0
  87. package/_cjs/services/Emailer/service.cjs.map +1 -0
  88. package/_cjs/services/Emailer.cjs +17 -0
  89. package/_cjs/services/Emailer.cjs.map +1 -0
  90. package/_cjs/services/Repository.cjs +247 -0
  91. package/_cjs/services/Repository.cjs.map +1 -0
  92. package/_cjs/services/ServiceBus.cjs +69 -0
  93. package/_cjs/services/ServiceBus.cjs.map +1 -0
  94. package/_cjs/services/Store/Cosmos.cjs +324 -0
  95. package/_cjs/services/Store/Cosmos.cjs.map +1 -0
  96. package/_cjs/services/Store/Cosmos.test.cjs +59 -0
  97. package/_cjs/services/Store/Cosmos.test.cjs.map +1 -0
  98. package/_cjs/services/Store/Disk.cjs +62 -0
  99. package/_cjs/services/Store/Disk.cjs.map +1 -0
  100. package/_cjs/services/Store/Memory.cjs +70 -0
  101. package/_cjs/services/Store/Memory.cjs.map +1 -0
  102. package/_cjs/services/Store/Redis.cjs +72 -0
  103. package/_cjs/services/Store/Redis.cjs.map +1 -0
  104. package/_cjs/services/Store/codeFilter.test.cjs +61 -0
  105. package/_cjs/services/Store/codeFilter.test.cjs.map +1 -0
  106. package/_cjs/services/Store/index.cjs +72 -0
  107. package/_cjs/services/Store/index.cjs.map +1 -0
  108. package/_cjs/services/Store/service.cjs +72 -0
  109. package/_cjs/services/Store/service.cjs.map +1 -0
  110. package/_cjs/services/Store/utils.cjs +78 -0
  111. package/_cjs/services/Store/utils.cjs.map +1 -0
  112. package/_cjs/services/Store.cjs +17 -0
  113. package/_cjs/services/Store.cjs.map +1 -0
  114. package/_cjs/services/memQueue.cjs +32 -0
  115. package/_cjs/services/memQueue.cjs.map +1 -0
  116. package/_cjs/test.arbs.cjs +32 -0
  117. package/_cjs/test.arbs.cjs.map +1 -0
  118. package/_cjs/vendor/Cache/Cache/_internal/AtomicBoolean.cjs +14 -0
  119. package/_cjs/vendor/Cache/Cache/_internal/AtomicBoolean.cjs.map +1 -0
  120. package/_cjs/vendor/Cache/Cache/_internal/AtomicNumber.cjs +29 -0
  121. package/_cjs/vendor/Cache/Cache/_internal/AtomicNumber.cjs.map +1 -0
  122. package/_cjs/vendor/Cache/Cache/_internal/AtomicReference.cjs +32 -0
  123. package/_cjs/vendor/Cache/Cache/_internal/AtomicReference.cjs.map +1 -0
  124. package/_cjs/vendor/Cache/Cache/_internal/CacheInternal.cjs +266 -0
  125. package/_cjs/vendor/Cache/Cache/_internal/CacheInternal.cjs.map +1 -0
  126. package/_cjs/vendor/Cache/Cache/_internal/CacheState.cjs +31 -0
  127. package/_cjs/vendor/Cache/Cache/_internal/CacheState.cjs.map +1 -0
  128. package/_cjs/vendor/Cache/Cache/_internal/KeySet.cjs +67 -0
  129. package/_cjs/vendor/Cache/Cache/_internal/KeySet.cjs.map +1 -0
  130. package/_cjs/vendor/Cache/Cache/_internal/MapKey.cjs +44 -0
  131. package/_cjs/vendor/Cache/Cache/_internal/MapKey.cjs.map +1 -0
  132. package/_cjs/vendor/Cache/Cache/_internal/MapValue.cjs +33 -0
  133. package/_cjs/vendor/Cache/Cache/_internal/MapValue.cjs.map +1 -0
  134. package/_cjs/vendor/Cache/Cache/definition.cjs +13 -0
  135. package/_cjs/vendor/Cache/Cache/definition.cjs.map +1 -0
  136. package/_cjs/vendor/Cache/Cache/operations/make.cjs +20 -0
  137. package/_cjs/vendor/Cache/Cache/operations/make.cjs.map +1 -0
  138. package/_cjs/vendor/Cache/Cache/operations/makeWith.cjs +23 -0
  139. package/_cjs/vendor/Cache/Cache/operations/makeWith.cjs.map +1 -0
  140. package/_cjs/vendor/Cache/Cache/operations.cjs +28 -0
  141. package/_cjs/vendor/Cache/Cache/operations.cjs.map +1 -0
  142. package/_cjs/vendor/Cache/Cache.cjs +28 -0
  143. package/_cjs/vendor/Cache/Cache.cjs.map +1 -0
  144. package/_cjs/vendor/Cache/CacheStats/definition.cjs +13 -0
  145. package/_cjs/vendor/Cache/CacheStats/definition.cjs.map +1 -0
  146. package/_cjs/vendor/Cache/CacheStats.cjs +17 -0
  147. package/_cjs/vendor/Cache/CacheStats.cjs.map +1 -0
  148. package/_cjs/vendor/Cache/EntryStats/definition.cjs +11 -0
  149. package/_cjs/vendor/Cache/EntryStats/definition.cjs.map +1 -0
  150. package/_cjs/vendor/Cache/EntryStats.cjs +17 -0
  151. package/_cjs/vendor/Cache/EntryStats.cjs.map +1 -0
  152. package/_cjs/vendor/Cache/Lookup/definition.cjs +6 -0
  153. package/_cjs/vendor/Cache/Lookup/definition.cjs.map +1 -0
  154. package/_cjs/vendor/Cache/Lookup.cjs +17 -0
  155. package/_cjs/vendor/Cache/Lookup.cjs.map +1 -0
  156. package/_cjs/vendor/Cache/index.cjs +17 -0
  157. package/_cjs/vendor/Cache/index.cjs.map +1 -0
  158. package/_src/_global.ext.ts +34 -0
  159. package/_src/_global.schema.ts +10 -0
  160. package/_src/_global.ts +14 -0
  161. package/_src/errors.ts +50 -0
  162. package/_src/ext.ts +1 -0
  163. package/_src/index.ts +0 -0
  164. package/_src/lib/RequestContext.ts +132 -0
  165. package/_src/lib/api/authorization.jwt.ts +52 -0
  166. package/_src/lib/api/defaultErrorHandler.ts +92 -0
  167. package/_src/lib/api/reportError.ts +50 -0
  168. package/_src/lib/api/routing.ts +623 -0
  169. package/_src/lib/api/setupRequest.ts +22 -0
  170. package/_src/lib/api/util.ts +14 -0
  171. package/_src/lib/api/writeDocs.ts +26 -0
  172. package/_src/lib/errorReporter.ts +63 -0
  173. package/_src/lib/ext/Array.ts +32 -0
  174. package/_src/lib/fileUtil.ts +56 -0
  175. package/_src/lib/filter/types/errors.ts +47 -0
  176. package/_src/lib/filter/types/fields.ts +50 -0
  177. package/_src/lib/filter/types/index.ts +5 -0
  178. package/_src/lib/filter/types/path/common.ts +404 -0
  179. package/_src/lib/filter/types/path/eager.ts +146 -0
  180. package/_src/lib/filter/types/path/index.ts +14 -0
  181. package/_src/lib/filter/types/utils.ts +106 -0
  182. package/_src/lib/filter/types/validator.ts +46 -0
  183. package/_src/lib/filter.ts +323 -0
  184. package/_src/lib/instrument.ts +9 -0
  185. package/_src/lib/rateLimit.ts +126 -0
  186. package/_src/services/CUPS/service.ts +16 -0
  187. package/_src/services/CUPS.ts +105 -0
  188. package/_src/services/Cache.ts +45 -0
  189. package/_src/services/Emailer/Sendgrid.ts +123 -0
  190. package/_src/services/Emailer/fake.ts +14 -0
  191. package/_src/services/Emailer/service.ts +33 -0
  192. package/_src/services/Emailer.ts +1 -0
  193. package/_src/services/Repository.ts +513 -0
  194. package/_src/services/ServiceBus.ts +111 -0
  195. package/_src/services/Store/Cosmos.test.ts +91 -0
  196. package/_src/services/Store/Cosmos.ts +545 -0
  197. package/_src/services/Store/Disk.ts +81 -0
  198. package/_src/services/Store/Memory.ts +77 -0
  199. package/_src/services/Store/Redis.ts +92 -0
  200. package/_src/services/Store/codeFilter.test.ts +74 -0
  201. package/_src/services/Store/index.test.ts.bak +112 -0
  202. package/_src/services/Store/index.ts +62 -0
  203. package/_src/services/Store/service.ts +174 -0
  204. package/_src/services/Store/utils.ts +126 -0
  205. package/_src/services/Store.ts +1 -0
  206. package/_src/services/memQueue.ts +30 -0
  207. package/_src/test.arbs.ts +27 -0
  208. package/_src/vendor/Cache/Cache/_internal/AtomicBoolean.ts +7 -0
  209. package/_src/vendor/Cache/Cache/_internal/AtomicNumber.ts +28 -0
  210. package/_src/vendor/Cache/Cache/_internal/AtomicReference.ts +30 -0
  211. package/_src/vendor/Cache/Cache/_internal/CacheInternal.ts +293 -0
  212. package/_src/vendor/Cache/Cache/_internal/CacheState.ts +56 -0
  213. package/_src/vendor/Cache/Cache/_internal/KeySet.ts +58 -0
  214. package/_src/vendor/Cache/Cache/_internal/MapKey.ts +43 -0
  215. package/_src/vendor/Cache/Cache/_internal/MapValue.ts +39 -0
  216. package/_src/vendor/Cache/Cache/definition.ts +112 -0
  217. package/_src/vendor/Cache/Cache/operations/make.ts +17 -0
  218. package/_src/vendor/Cache/Cache/operations/makeWith.ts +32 -0
  219. package/_src/vendor/Cache/Cache/operations.ts +4 -0
  220. package/_src/vendor/Cache/Cache.ts +4 -0
  221. package/_src/vendor/Cache/CacheStats/definition.ts +23 -0
  222. package/_src/vendor/Cache/CacheStats.ts +3 -0
  223. package/_src/vendor/Cache/EntryStats/definition.ts +19 -0
  224. package/_src/vendor/Cache/EntryStats.ts +3 -0
  225. package/_src/vendor/Cache/Lookup/definition.ts +15 -0
  226. package/_src/vendor/Cache/Lookup.ts +3 -0
  227. package/_src/vendor/Cache/global.ts.bak +23 -0
  228. package/_src/vendor/Cache/index.ts +4 -0
  229. package/dist/_global.d.ts +10 -0
  230. package/dist/_global.d.ts.map +1 -0
  231. package/dist/_global.ext.d.ts +34 -0
  232. package/dist/_global.ext.d.ts.map +1 -0
  233. package/dist/_global.ext.js +2 -0
  234. package/dist/_global.js +12 -0
  235. package/dist/_global.schema.d.ts +6 -0
  236. package/dist/_global.schema.d.ts.map +1 -0
  237. package/dist/_global.schema.js +9 -0
  238. package/dist/errors.d.ts +41 -0
  239. package/dist/errors.d.ts.map +1 -0
  240. package/dist/errors.js +51 -0
  241. package/dist/ext.d.ts +2 -0
  242. package/dist/ext.d.ts.map +1 -0
  243. package/dist/ext.js +2 -0
  244. package/dist/index.d.ts +2 -0
  245. package/dist/index.d.ts.map +1 -0
  246. package/dist/index.js +2 -0
  247. package/dist/lib/RequestContext.d.ts +122 -0
  248. package/dist/lib/RequestContext.d.ts.map +1 -0
  249. package/dist/lib/RequestContext.js +52 -0
  250. package/dist/lib/api/authorization.jwt.d.ts +7 -0
  251. package/dist/lib/api/authorization.jwt.d.ts.map +1 -0
  252. package/dist/lib/api/authorization.jwt.js +32 -0
  253. package/dist/lib/api/defaultErrorHandler.d.ts +8 -0
  254. package/dist/lib/api/defaultErrorHandler.d.ts.map +1 -0
  255. package/dist/lib/api/defaultErrorHandler.js +37 -0
  256. package/dist/lib/api/reportError.d.ts +32 -0
  257. package/dist/lib/api/reportError.d.ts.map +1 -0
  258. package/dist/lib/api/reportError.js +44 -0
  259. package/dist/lib/api/routing.d.ts +100 -0
  260. package/dist/lib/api/routing.d.ts.map +1 -0
  261. package/dist/lib/api/routing.js +248 -0
  262. package/dist/lib/api/setupRequest.d.ts +13 -0
  263. package/dist/lib/api/setupRequest.d.ts.map +1 -0
  264. package/dist/lib/api/setupRequest.js +25 -0
  265. package/dist/lib/api/util.d.ts +3 -0
  266. package/dist/lib/api/util.d.ts.map +1 -0
  267. package/dist/lib/api/util.js +14 -0
  268. package/dist/lib/api/writeDocs.d.ts +3 -0
  269. package/dist/lib/api/writeDocs.d.ts.map +1 -0
  270. package/dist/lib/api/writeDocs.js +23 -0
  271. package/dist/lib/errorReporter.d.ts +8 -0
  272. package/dist/lib/errorReporter.d.ts.map +1 -0
  273. package/dist/lib/errorReporter.js +45 -0
  274. package/dist/lib/ext/Array.d.ts +19 -0
  275. package/dist/lib/ext/Array.d.ts.map +1 -0
  276. package/dist/lib/ext/Array.js +21 -0
  277. package/dist/lib/fileUtil.d.ts +22 -0
  278. package/dist/lib/fileUtil.d.ts.map +1 -0
  279. package/dist/lib/fileUtil.js +23 -0
  280. package/dist/lib/filter/types/errors.d.ts +30 -0
  281. package/dist/lib/filter/types/errors.d.ts.map +1 -0
  282. package/dist/lib/filter/types/errors.js +2 -0
  283. package/dist/lib/filter/types/fields.d.ts +29 -0
  284. package/dist/lib/filter/types/fields.d.ts.map +1 -0
  285. package/dist/lib/filter/types/fields.js +2 -0
  286. package/dist/lib/filter/types/index.d.ts +6 -0
  287. package/dist/lib/filter/types/index.d.ts.map +1 -0
  288. package/dist/lib/filter/types/index.js +6 -0
  289. package/dist/lib/filter/types/path/common.d.ts +316 -0
  290. package/dist/lib/filter/types/path/common.d.ts.map +1 -0
  291. package/dist/lib/filter/types/path/common.js +2 -0
  292. package/dist/lib/filter/types/path/eager.d.ts +95 -0
  293. package/dist/lib/filter/types/path/eager.d.ts.map +1 -0
  294. package/dist/lib/filter/types/path/eager.js +2 -0
  295. package/dist/lib/filter/types/path/index.d.ts +4 -0
  296. package/dist/lib/filter/types/path/index.d.ts.map +1 -0
  297. package/dist/lib/filter/types/path/index.js +4 -0
  298. package/dist/lib/filter/types/utils.d.ts +68 -0
  299. package/dist/lib/filter/types/utils.d.ts.map +1 -0
  300. package/dist/lib/filter/types/utils.js +2 -0
  301. package/dist/lib/filter/types/validator.d.ts +30 -0
  302. package/dist/lib/filter/types/validator.d.ts.map +1 -0
  303. package/dist/lib/filter/types/validator.js +2 -0
  304. package/dist/lib/filter.d.ts +133 -0
  305. package/dist/lib/filter.d.ts.map +1 -0
  306. package/dist/lib/filter.js +171 -0
  307. package/dist/lib/instrument.d.ts +7 -0
  308. package/dist/lib/instrument.d.ts.map +1 -0
  309. package/dist/lib/instrument.js +12 -0
  310. package/dist/lib/rateLimit.d.ts +43 -0
  311. package/dist/lib/rateLimit.d.ts.map +1 -0
  312. package/dist/lib/rateLimit.js +76 -0
  313. package/dist/services/CUPS/service.d.ts +19 -0
  314. package/dist/services/CUPS/service.d.ts.map +1 -0
  315. package/dist/services/CUPS/service.js +5 -0
  316. package/dist/services/CUPS.d.ts +10 -0
  317. package/dist/services/CUPS.d.ts.map +1 -0
  318. package/dist/services/CUPS.js +89 -0
  319. package/dist/services/Cache.d.ts +28 -0
  320. package/dist/services/Cache.d.ts.map +1 -0
  321. package/dist/services/Cache.js +28 -0
  322. package/dist/services/Emailer/Sendgrid.d.ts +180 -0
  323. package/dist/services/Emailer/Sendgrid.d.ts.map +1 -0
  324. package/dist/services/Emailer/Sendgrid.js +102 -0
  325. package/dist/services/Emailer/fake.d.ts +7 -0
  326. package/dist/services/Emailer/fake.d.ts.map +1 -0
  327. package/dist/services/Emailer/fake.js +15 -0
  328. package/dist/services/Emailer/service.d.ts +41 -0
  329. package/dist/services/Emailer/service.d.ts.map +1 -0
  330. package/dist/services/Emailer/service.js +3 -0
  331. package/dist/services/Emailer.d.ts +2 -0
  332. package/dist/services/Emailer.d.ts.map +1 -0
  333. package/dist/services/Emailer.js +2 -0
  334. package/dist/services/Repository.d.ts +300 -0
  335. package/dist/services/Repository.d.ts.map +1 -0
  336. package/dist/services/Repository.js +193 -0
  337. package/dist/services/ServiceBus.d.ts +26 -0
  338. package/dist/services/ServiceBus.d.ts.map +1 -0
  339. package/dist/services/ServiceBus.js +53 -0
  340. package/dist/services/Store/Cosmos.d.ts +56 -0
  341. package/dist/services/Store/Cosmos.d.ts.map +1 -0
  342. package/dist/services/Store/Cosmos.js +321 -0
  343. package/dist/services/Store/Cosmos.test.d.ts.map +1 -0
  344. package/dist/services/Store/Disk.d.ts +14 -0
  345. package/dist/services/Store/Disk.d.ts.map +1 -0
  346. package/dist/services/Store/Disk.js +52 -0
  347. package/dist/services/Store/Memory.d.ts +17 -0
  348. package/dist/services/Store/Memory.d.ts.map +1 -0
  349. package/dist/services/Store/Memory.js +60 -0
  350. package/dist/services/Store/Redis.d.ts +12 -0
  351. package/dist/services/Store/Redis.d.ts.map +1 -0
  352. package/dist/services/Store/Redis.js +59 -0
  353. package/dist/services/Store/codeFilter.test.d.ts.map +1 -0
  354. package/dist/services/Store/index.d.ts +10 -0
  355. package/dist/services/Store/index.d.ts.map +1 -0
  356. package/dist/services/Store/index.js +52 -0
  357. package/dist/services/Store/service.d.ts +113 -0
  358. package/dist/services/Store/service.d.ts.map +1 -0
  359. package/dist/services/Store/service.js +63 -0
  360. package/dist/services/Store/utils.d.ts +14 -0
  361. package/dist/services/Store/utils.d.ts.map +1 -0
  362. package/dist/services/Store/utils.js +103 -0
  363. package/dist/services/Store.d.ts +2 -0
  364. package/dist/services/Store.d.ts.map +1 -0
  365. package/dist/services/Store.js +2 -0
  366. package/dist/services/memQueue.d.ts +18 -0
  367. package/dist/services/memQueue.d.ts.map +1 -0
  368. package/dist/services/memQueue.js +24 -0
  369. package/dist/test.arbs.d.ts +13 -0
  370. package/dist/test.arbs.d.ts.map +1 -0
  371. package/dist/test.arbs.js +22 -0
  372. package/dist/vendor/Cache/Cache/_internal/AtomicBoolean.d.ts +5 -0
  373. package/dist/vendor/Cache/Cache/_internal/AtomicBoolean.d.ts.map +1 -0
  374. package/dist/vendor/Cache/Cache/_internal/AtomicBoolean.js +7 -0
  375. package/dist/vendor/Cache/Cache/_internal/AtomicNumber.d.ts +8 -0
  376. package/dist/vendor/Cache/Cache/_internal/AtomicNumber.d.ts.map +1 -0
  377. package/dist/vendor/Cache/Cache/_internal/AtomicNumber.js +22 -0
  378. package/dist/vendor/Cache/Cache/_internal/AtomicReference.d.ts +10 -0
  379. package/dist/vendor/Cache/Cache/_internal/AtomicReference.d.ts.map +1 -0
  380. package/dist/vendor/Cache/Cache/_internal/AtomicReference.js +25 -0
  381. package/dist/vendor/Cache/Cache/_internal/CacheInternal.d.ts +51 -0
  382. package/dist/vendor/Cache/Cache/_internal/CacheInternal.d.ts.map +1 -0
  383. package/dist/vendor/Cache/Cache/_internal/CacheInternal.js +253 -0
  384. package/dist/vendor/Cache/Cache/_internal/CacheState.d.ts +33 -0
  385. package/dist/vendor/Cache/Cache/_internal/CacheState.d.ts.map +1 -0
  386. package/dist/vendor/Cache/Cache/_internal/CacheState.js +21 -0
  387. package/dist/vendor/Cache/Cache/_internal/KeySet.d.ts +20 -0
  388. package/dist/vendor/Cache/Cache/_internal/KeySet.d.ts.map +1 -0
  389. package/dist/vendor/Cache/Cache/_internal/KeySet.js +61 -0
  390. package/dist/vendor/Cache/Cache/_internal/MapKey.d.ts +24 -0
  391. package/dist/vendor/Cache/Cache/_internal/MapKey.d.ts.map +1 -0
  392. package/dist/vendor/Cache/Cache/_internal/MapKey.js +37 -0
  393. package/dist/vendor/Cache/Cache/_internal/MapValue.d.ts +32 -0
  394. package/dist/vendor/Cache/Cache/_internal/MapValue.d.ts.map +1 -0
  395. package/dist/vendor/Cache/Cache/_internal/MapValue.js +24 -0
  396. package/dist/vendor/Cache/Cache/definition.d.ts +100 -0
  397. package/dist/vendor/Cache/Cache/definition.d.ts.map +1 -0
  398. package/dist/vendor/Cache/Cache/definition.js +5 -0
  399. package/dist/vendor/Cache/Cache/operations/make.d.ts +12 -0
  400. package/dist/vendor/Cache/Cache/operations/make.d.ts.map +1 -0
  401. package/dist/vendor/Cache/Cache/operations/make.js +12 -0
  402. package/dist/vendor/Cache/Cache/operations/makeWith.d.ts +14 -0
  403. package/dist/vendor/Cache/Cache/operations/makeWith.d.ts.map +1 -0
  404. package/dist/vendor/Cache/Cache/operations/makeWith.js +15 -0
  405. package/dist/vendor/Cache/Cache/operations.d.ts +3 -0
  406. package/dist/vendor/Cache/Cache/operations.d.ts.map +1 -0
  407. package/dist/vendor/Cache/Cache/operations.js +4 -0
  408. package/dist/vendor/Cache/Cache.d.ts +3 -0
  409. package/dist/vendor/Cache/Cache.d.ts.map +1 -0
  410. package/dist/vendor/Cache/Cache.js +4 -0
  411. package/dist/vendor/Cache/CacheStats/definition.d.ts +19 -0
  412. package/dist/vendor/Cache/CacheStats/definition.d.ts.map +1 -0
  413. package/dist/vendor/Cache/CacheStats/definition.js +6 -0
  414. package/dist/vendor/Cache/CacheStats.d.ts +2 -0
  415. package/dist/vendor/Cache/CacheStats.d.ts.map +1 -0
  416. package/dist/vendor/Cache/CacheStats.js +3 -0
  417. package/dist/vendor/Cache/EntryStats/definition.d.ts +17 -0
  418. package/dist/vendor/Cache/EntryStats/definition.d.ts.map +1 -0
  419. package/dist/vendor/Cache/EntryStats/definition.js +4 -0
  420. package/dist/vendor/Cache/EntryStats.d.ts +2 -0
  421. package/dist/vendor/Cache/EntryStats.d.ts.map +1 -0
  422. package/dist/vendor/Cache/EntryStats.js +3 -0
  423. package/dist/vendor/Cache/Lookup/definition.d.ts +17 -0
  424. package/dist/vendor/Cache/Lookup/definition.d.ts.map +1 -0
  425. package/dist/vendor/Cache/Lookup/definition.js +2 -0
  426. package/dist/vendor/Cache/Lookup.d.ts +2 -0
  427. package/dist/vendor/Cache/Lookup.d.ts.map +1 -0
  428. package/dist/vendor/Cache/Lookup.js +3 -0
  429. package/dist/vendor/Cache/index.d.ts +5 -0
  430. package/dist/vendor/Cache/index.d.ts.map +1 -0
  431. package/dist/vendor/Cache/index.js +5 -0
  432. package/package.json +756 -0
  433. package/tsconfig.json +107 -0
  434. package/tsconfig.json.bak +47 -0
  435. package/tsplus.config.json +6 -0
  436. package/types/modules.d.ts +1 -0
  437. package/vitest.config.ts +5 -0
  438. package/wallaby.cjs +1 -0
@@ -0,0 +1,92 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import * as RedisClient from "@effect-app/infra-adapters/redis-client"
3
+ import { NotFoundError } from "../../errors.js"
4
+ import { memFilter } from "./Memory.js"
5
+
6
+ import type { Filter, FilterJoinSelect, PersistenceModelType, StorageConfig, Store, StoreConfig } from "./service.js"
7
+ import { StoreMaker } from "./service.js"
8
+ import { codeFilterJoinSelect, makeETag, makeUpdateETag } from "./utils.js"
9
+
10
+ export function makeRedisStore({ prefix }: StorageConfig) {
11
+ return Effect.gen(function*($) {
12
+ const redis = yield* $(RedisClient.RedisClient.access)
13
+ return {
14
+ make: <Id extends string, PM extends PersistenceModelType<Id>, Id2 extends Id>(
15
+ name: string,
16
+ existing?: Effect<never, never, ROMap<Id2, PM>>,
17
+ _config?: StoreConfig<PM>
18
+ ) =>
19
+ Effect.gen(function*($) {
20
+ const updateETag = makeUpdateETag(name)
21
+ // Very naive implementation of course.
22
+ const key = `${prefix}${name}`
23
+ const current = yield* $(RedisClient.get(key).orDie.provideService(RedisClient.RedisClient, redis))
24
+ if (!current.isSome()) {
25
+ const m = yield* $(existing ?? Effect(ROMap.empty))
26
+ yield* $(
27
+ RedisClient.set(key, JSON.stringify({ data: [...m.values()].map(e => makeETag(e)) }))
28
+ .orDie
29
+ .provideService(RedisClient.RedisClient, redis)
30
+ )
31
+ }
32
+ const get = RedisClient.get(key)
33
+ .flatMap(x => x.encaseInEffect(() => new NotFoundError("data", "")))
34
+ .orDie
35
+ .map(x => JSON.parse(x) as { data: readonly PM[] })
36
+ .map(_ => _.data)
37
+ .provideService(RedisClient.RedisClient, redis)
38
+
39
+ const set = (i: ROMap<Id, PM>) => RedisClient.set(key, JSON.stringify({ data: [...i.values()] })).orDie
40
+
41
+ const sem = Semaphore.unsafeMake(1)
42
+ const withPermit = sem.withPermits(1)
43
+
44
+ const asMap = get.map(x => ROMap.make(x.map(x => [x.id, x] as const)))
45
+ const all = get.map(Chunk.fromIterable)
46
+ const batchSet = (items: NonEmptyReadonlyArray<PM>) =>
47
+ items
48
+ .forEachEffect(e => s.find(e.id).flatMap(current => updateETag(e, current)))
49
+ .tap(items =>
50
+ asMap
51
+ .map(m => {
52
+ const mut = ROMap.toMutable(m)
53
+ items.forEach(e => mut.set(e.id, e))
54
+ return ROMap.fromMutable(mut)
55
+ })
56
+ .flatMap(set)
57
+ )
58
+ .map(_ => _.toReadonlyArray() as NonEmptyReadonlyArray<PM>)
59
+ .apply(withPermit)
60
+ .provideService(RedisClient.RedisClient, redis)
61
+ const s: Store<PM, Id> = {
62
+ all,
63
+ filter: (filter: Filter<PM>, cursor?: { skip?: number; limit?: number }) =>
64
+ all.map(memFilter(filter, cursor)),
65
+ filterJoinSelect: <T extends object>(filter: FilterJoinSelect) =>
66
+ all.map(c => c.flatMap(codeFilterJoinSelect<PM, T>(filter))),
67
+ find: id => asMap.map(ROMap.lookup(id)),
68
+ set: e =>
69
+ s
70
+ .find(e.id)
71
+ .flatMap(current => updateETag(e, current))
72
+ .tap(e => asMap.map(ROMap.insert(e.id, e)).flatMap(set))
73
+ .apply(withPermit)
74
+ .provideService(RedisClient.RedisClient, redis),
75
+ batchSet,
76
+ bulkSet: batchSet,
77
+ remove: (e: PM) =>
78
+ asMap.map(ROMap.remove(e.id)).flatMap(set)
79
+ .apply(withPermit)
80
+ .provideService(
81
+ RedisClient.RedisClient,
82
+ redis
83
+ )
84
+ }
85
+ return s
86
+ })
87
+ }
88
+ })
89
+ }
90
+ export function RedisStoreLive(config: Config<StorageConfig>) {
91
+ return config.config.flatMap(makeRedisStore).toLayer(StoreMaker)
92
+ }
@@ -0,0 +1,74 @@
1
+ import { expect, test } from "vitest"
2
+ import type { StoreWhereFilter, Where } from "@effect-app/infra/services/Store"
3
+ import { makeFilters } from "../../lib/filter.js"
4
+ import { codeFilter } from "./utils.js"
5
+
6
+
7
+ const somethings = [
8
+ {a: 1, b: "b", c: ["c"], d: [{a: "a2", b: 1}, {a: "a", b: 1}], id: "1"},
9
+ {a: 2, b: "b2", c: ["c2"], d: [{a: "a4", b: 2}, {a: "a5", b: 2}], id: "2"},
10
+ ] satisfies readonly Something[]
11
+
12
+ const f_ = makeFilters<Something>()
13
+ export type SomethingWhereFilter = typeof f_
14
+
15
+ export function makeSomethingFilter_(filter: (f: SomethingWhereFilter) => StoreWhereFilter) {
16
+ return filter(f_)
17
+ }
18
+
19
+ export function somethingsWhere(
20
+ makeWhere: (
21
+ f: SomethingWhereFilter
22
+ ) => Where | [Where, ...Where[]],
23
+ mode?: "or" | "and"
24
+ ) {
25
+ return makeSomethingFilter_(f => {
26
+ const m = makeWhere ? makeWhere(f) : []
27
+ return ({
28
+ mode,
29
+ where: (Array.isArray(m) ? m as unknown as [Where, ...Where[]] : [m]) as readonly [Where, ...Where[]]
30
+ })
31
+ })
32
+ }
33
+
34
+
35
+ type SomethingElse = {
36
+ a: string,
37
+ b: number
38
+ }
39
+
40
+ type Something = {
41
+ a: number,
42
+ id: string,
43
+ b: string,
44
+ c: readonly string[]
45
+ d: readonly SomethingElse[]
46
+ }
47
+
48
+ test("works", () => {
49
+ expect(somethings.filterMap(codeFilter(
50
+ somethingsWhere(_ => _("b", _ => "b2"))
51
+ )).toArray)
52
+ .toEqual([somethings[1]])
53
+
54
+ expect(somethings.filterMap(codeFilter(
55
+ somethingsWhere(_ => _("b", _ => "b"))
56
+ )).toArray)
57
+ .toEqual([somethings[0]])
58
+
59
+
60
+ expect(somethings.filterMap(codeFilter(
61
+ somethingsWhere(_ => _("d.-1.a", _ => "a5"))
62
+ )).toArray)
63
+ .toEqual([somethings[1]])
64
+
65
+ expect(somethings.filterMap(codeFilter(
66
+ somethingsWhere(_ => _("d.-1.a", _ => "a"))
67
+ )).toArray)
68
+ .toEqual([somethings[0]])
69
+
70
+ expect(somethings.filterMap(codeFilter(
71
+ somethingsWhere(_ => _("d.-1.a", _ => _.$isnt("a")))
72
+ )).toArray)
73
+ .toEqual([somethings[1]])
74
+ })
@@ -0,0 +1,112 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import * as Test from "@effect-ts/jest/Test"
3
+ import { describe, expect } from "@jest/globals"
4
+
5
+ import { OptimisticConcurrencyException } from "../../errors.js"
6
+
7
+ import { makeMemoryStore } from "./Memory.js"
8
+
9
+ const { it } = Test.runtime()
10
+
11
+ describe("Optimistic Concurrency", () => {
12
+ describe("set", () => {
13
+ it("works", () =>
14
+ Effect.gen(function*($) {
15
+ const existing = new Map<
16
+ string,
17
+ { _etag: string | undefined; id: string; a: string }
18
+ >()
19
+ const { make } = makeMemoryStore()
20
+ const store = yield* $(make("test", Effect(existing)))
21
+
22
+ const result1 = yield* $(store.set({ id: "1", a: "string", _etag: undefined }))
23
+ const result2_1 = yield* $(
24
+ store.set({ id: "2", a: "string", _etag: undefined })
25
+ )
26
+ const result2 = yield* $(store.set({ ...result1, a: "another-string" }))
27
+ const result3 = yield* $(store.set({ ...result2, a: "another-string2" }))
28
+ const failResult = yield* $(
29
+ store.set({ ...result1, a: "another-string3" }).result
30
+ )
31
+ expect(result1._etag).toBeTruthy()
32
+ expect(result2_1._etag).toBeTruthy()
33
+ expect(result2._etag).toBeTruthy()
34
+ expect(result3._etag).toBeTruthy()
35
+
36
+ expect(result2._etag).not.toEqual(result1._etag)
37
+ expect(result3._etag).not.toEqual(result2._etag)
38
+
39
+ expect(Exit.untraced(failResult)).toEqual(
40
+ Exit.fail(new OptimisticConcurrencyException("test", "1"))
41
+ )
42
+ console.log({ result1, result2 })
43
+ }))
44
+ })
45
+
46
+ describe("bulkSet", () => {
47
+ it("works", () =>
48
+ Effect.gen(function*($) {
49
+ const existing = new Map<
50
+ string,
51
+ { _etag: string | undefined; id: string; a: string }
52
+ >()
53
+ const { make } = makeMemoryStore()
54
+ const store = yield* $(make("test", Effect(existing)))
55
+
56
+ const [result1] = yield* $(
57
+ store.bulkSet([{ id: "1", a: "string", _etag: undefined }])
58
+ )
59
+ const [result2_1] = yield* $(
60
+ store.bulkSet([{ id: "2", a: "string", _etag: undefined }])
61
+ )
62
+ const [result2] = yield* $(store.bulkSet([{ ...result1, a: "another-string" }]))
63
+ const [result3] = yield* $(
64
+ store.bulkSet([{ ...result2, a: "another-string2" }])
65
+ )
66
+ const failResult = yield* $(
67
+ store.bulkSet([{ ...result1, a: "another-string3" }]).result
68
+ )
69
+ expect(result1._etag).toBeTruthy()
70
+ expect(result2_1._etag).toBeTruthy()
71
+ expect(result2._etag).toBeTruthy()
72
+ expect(result3._etag).toBeTruthy()
73
+
74
+ expect(result2._etag).not.toEqual(result1._etag)
75
+ expect(result3._etag).not.toEqual(result2._etag)
76
+
77
+ expect(Exit.untraced(failResult)).toEqual(
78
+ Exit.fail(new OptimisticConcurrencyException("test", "1"))
79
+ )
80
+ console.log({ result1, result2 })
81
+ }))
82
+ })
83
+
84
+ describe("batchSet", () => {
85
+ it("works", () =>
86
+ Effect.gen(function*($) {
87
+ const existing = new Map<
88
+ string,
89
+ { _etag: string | undefined; id: string; a: string }
90
+ >()
91
+ const { make } = makeMemoryStore()
92
+ const store = yield* $(make("test", Effect(existing)))
93
+
94
+ const item1 = { id: "1", a: "string", _etag: undefined }
95
+ const item2 = { id: "2", a: "string", _etag: undefined }
96
+
97
+ yield* $(store.batchSet([item1, item2]))
98
+
99
+ const [result1, result2] = yield* $(
100
+ Effect.collectAll([store.find("1"), store.find("2")])
101
+ )
102
+ const failResult = yield* $(
103
+ store.batchSet([{ id: "1", a: "another-string3", _etag: "abc" }]).result
104
+ )
105
+ expect(result1).toEqual(Opt({ ...item1, _etag: expect.any(String) }))
106
+ expect(result2).toEqual(Opt({ ...item2, _etag: expect.any(String) }))
107
+ expect(Exit.untraced(failResult)).toEqual(
108
+ Exit.fail(new OptimisticConcurrencyException("test", "1"))
109
+ )
110
+ }))
111
+ })
112
+ })
@@ -0,0 +1,62 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import * as CosmosClient from "@effect-app/infra-adapters/cosmos-client"
3
+ import * as RedisClient from "@effect-app/infra-adapters/redis-client"
4
+ import { createClient } from "redis"
5
+
6
+ import { makeCosmosStore } from "./Cosmos.js"
7
+ import { makeDiskStore } from "./Disk.js"
8
+ import { makeMemoryStore } from "./Memory.js"
9
+ import { makeRedisStore } from "./Redis.js"
10
+ import type { StorageConfig } from "./service.js"
11
+ import { StoreMaker } from "./service.js"
12
+
13
+ /**
14
+ * @tsplus static StoreMaker.Ops Live
15
+ */
16
+ export function StoreMakerLive(config: Config<StorageConfig>) {
17
+ return config.config.flatMap(cfg => {
18
+ const storageUrl = cfg.url.value
19
+ if (storageUrl.startsWith("mem://")) {
20
+ console.log("Using in memory store")
21
+ return Effect(makeMemoryStore())
22
+ }
23
+ if (storageUrl.startsWith("disk://")) {
24
+ console.log("Using disk store at ./.data")
25
+ return makeDiskStore(cfg)
26
+ }
27
+ if (storageUrl.startsWith("redis://")) {
28
+ console.log("Using Redis store")
29
+ return RedisClient.makeRedisClient(makeRedis(storageUrl)).flatMap(client =>
30
+ makeRedisStore(cfg).provideService(
31
+ RedisClient.RedisClient,
32
+ client
33
+ )
34
+ )
35
+ }
36
+
37
+ console.log("Using Cosmos DB store")
38
+ return CosmosClient.makeCosmosClient(storageUrl, cfg.dbName).flatMap(client =>
39
+ makeCosmosStore(cfg).provideService(CosmosClient.CosmosClient, client)
40
+ )
41
+ })
42
+ .toScopedLayer(StoreMaker)
43
+ }
44
+
45
+ function makeRedis(storageUrl: string) {
46
+ const url = new URL(storageUrl)
47
+ const hostname = url.hostname
48
+ const password = url.password
49
+ return () =>
50
+ createClient(
51
+ storageUrl === "redis://"
52
+ ? ({
53
+ host: hostname,
54
+ port: 6380,
55
+ auth_pass: password,
56
+ tls: { servername: hostname }
57
+ } as any)
58
+ : (storageUrl as any)
59
+ )
60
+ }
61
+
62
+ export * from "./service.js"
@@ -0,0 +1,174 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import type { UniqueKey } from "@azure/cosmos"
3
+ import type { Parser, ParserEnv } from "@effect-app/schema/custom/Parser"
4
+
5
+ import type { These } from "@effect-app/prelude/schema"
6
+ import type { OptimisticConcurrencyException } from "../../errors.js"
7
+
8
+ export type StoreConfig<E> = {
9
+ uniqueKeys?: UniqueKey[]
10
+ maxBulkSize?: number
11
+ partitionValue: (e: E) => string | undefined
12
+ }
13
+
14
+ export type SupportedValues = string | boolean | number | null
15
+
16
+ // default is eq
17
+ export type Where = { key: string; t?: "eq" | "not-eq"; value: SupportedValues } | {
18
+ key: string
19
+ t: "in" | "not-in"
20
+ value: readonly (SupportedValues)[]
21
+ }
22
+
23
+ // default is where
24
+ export type StoreWhereFilter = {
25
+ type?: "where"
26
+ mode?: "and" | "or" // default is and
27
+ where: readonly [
28
+ Where,
29
+ ...(Where[])
30
+ ]
31
+ }
32
+ export type LegacyFilter<E> =
33
+ | { by: keyof E; type: "startsWith"; value: any }
34
+ | { by: keyof E; type: "endsWith"; value: any }
35
+ | { by: keyof E; type: "contains"; value: any }
36
+ export type JoinFindFilter = {
37
+ type: "join_find"
38
+ keys: readonly string[] /* value paths of E */
39
+ valueKey: string /* value paths of E[keys][valueKey] */
40
+ value: any /* value path[valueKey] of E */
41
+ }
42
+ export type Filter<E> =
43
+ | JoinFindFilter
44
+ | StoreWhereFilter
45
+ | LegacyFilter<E>
46
+
47
+ export type FilterJoinSelect = {
48
+ type: "filter_join_select"
49
+ keys: readonly string[] /* value paths of E */
50
+ valueKey: string /* value paths of E[keys][valueKey] */
51
+ value: any /* value path[valueKey] of E */
52
+ }
53
+
54
+ export interface Store<PM extends PersistenceModelType<Id>, Id extends string> {
55
+ all: Effect<never, never, Chunk<PM>>
56
+ filter: (
57
+ filter: Filter<PM>,
58
+ cursor?: { limit?: number; skip?: number }
59
+ ) => Effect<never, never, Chunk<PM>>
60
+ filterJoinSelect: <T extends object>(
61
+ filter: FilterJoinSelect
62
+ ) => Effect<never, never, Chunk<T & { _rootId: string }>>
63
+ find: (id: Id) => Effect<never, never, Opt<PM>>
64
+ set: (e: PM) => Effect<never, OptimisticConcurrencyException, PM>
65
+ batchSet: (
66
+ items: NonEmptyReadonlyArray<PM>
67
+ ) => Effect<never, OptimisticConcurrencyException, NonEmptyReadonlyArray<PM>>
68
+ bulkSet: (
69
+ items: NonEmptyReadonlyArray<PM>
70
+ ) => Effect<never, OptimisticConcurrencyException, NonEmptyReadonlyArray<PM>>
71
+ /**
72
+ * Requires the PM type, not Id, because various stores may need to calculate e.g partition keys.
73
+ */
74
+ remove: (e: PM) => Effect<never, never, void>
75
+ }
76
+
77
+ export interface StoreMaker {
78
+ make: <E extends PersistenceModelType<Id>, Id extends string, Id2 extends Id>(
79
+ name: string,
80
+ existing?: Effect<never, never, ROMap<Id2, E>>,
81
+ config?: StoreConfig<E>
82
+ ) => Effect<never, never, Store<E, Id>>
83
+ }
84
+
85
+ /**
86
+ * @tsplus type StoreMaker.Ops
87
+ */
88
+ export interface StoreMakerOps extends Tag<StoreMaker> {}
89
+ export const StoreMaker: StoreMakerOps = Tag<StoreMaker>()
90
+
91
+ /**
92
+ * @tsplus static ContextMap.Ops Make
93
+ */
94
+ export const makeMap = Effect(() => {
95
+ const etags = ROMap.make<string, string>([])["|>"](ROMap.toMutable)
96
+ const getEtag = (id: string) => etags.get(id)
97
+ const setEtag = (id: string, eTag: string | undefined) => {
98
+ eTag === undefined ? etags.delete(id) : etags.set(id, eTag)
99
+ }
100
+
101
+ const parsedCache = ROMap.make<
102
+ Parser<any, any, any>,
103
+ Map<unknown, These.These<unknown, unknown>>
104
+ >([])["|>"](ROMap.toMutable)
105
+
106
+ const parserCache = ROMap.make<
107
+ Parser<any, any, any>,
108
+ (i: any) => These.These<any, any>
109
+ >([])["|>"](ROMap.toMutable)
110
+
111
+ const setAndReturn = <I, E, A>(
112
+ p: Parser<I, E, A>,
113
+ np: (i: I) => These.These<E, A>
114
+ ) => {
115
+ parserCache.set(p, np)
116
+ return np
117
+ }
118
+
119
+ const parserEnv: ParserEnv = {
120
+ // TODO: lax: true would turn off refinement checks, may help on large payloads
121
+ // but of course removes confirming of validation rules (which may be okay for a database owned by the app, as we write safely)
122
+ lax: false,
123
+ cache: {
124
+ getOrSetParser: p => parserCache.get(p) ?? setAndReturn(p, i => parserEnv.cache!.getOrSet(i, p)),
125
+ getOrSetParsers: parsers => {
126
+ return Object.entries(parsers).reduce((prev, [k, v]) => {
127
+ prev[k] = parserEnv.cache!.getOrSetParser(v)
128
+ return prev
129
+ }, {} as any)
130
+ },
131
+ getOrSet: (i, parse): any => {
132
+ const c = parsedCache.get(parse)
133
+ if (c) {
134
+ const f = c.get(i)
135
+ if (f) {
136
+ // console.log("$$$ cache hit", i)
137
+ return f
138
+ } else {
139
+ const nf = parse(i, parserEnv)
140
+ c.set(i, nf)
141
+ return nf
142
+ }
143
+ } else {
144
+ const nf = parse(i, parserEnv)
145
+ parsedCache.set(parse, ROMap.make([[i, nf]])["|>"](ROMap.toMutable))
146
+ return nf
147
+ }
148
+ }
149
+ }
150
+ }
151
+
152
+ return {
153
+ get: getEtag,
154
+ set: setEtag,
155
+ parserEnv
156
+ }
157
+ })
158
+ export interface ContextMap extends Effect.Success<typeof makeMap> {}
159
+ /**
160
+ * @tsplus type ContextMap.Ops
161
+ */
162
+ export interface ContextMapOps extends Tag<ContextMap> {}
163
+ export const ContextMap: ContextMapOps = Tag<ContextMap>()
164
+
165
+ export interface PersistenceModelType<Id extends string> {
166
+ id: Id
167
+ _etag: string | undefined
168
+ }
169
+
170
+ export interface StorageConfig {
171
+ url: ConfigSecret
172
+ prefix: string
173
+ dbName: string
174
+ }
@@ -0,0 +1,126 @@
1
+ import { get } from "@effect-app/prelude/utils"
2
+
3
+ import { OptimisticConcurrencyException } from "../../errors.js"
4
+
5
+ import type { Filter, FilterJoinSelect, PersistenceModelType } from "./service.js"
6
+
7
+ import objectHash from "object-hash"
8
+
9
+ export const makeETag = <E extends PersistenceModelType<Id>, Id extends string>(
10
+ { _etag, ...e }: E
11
+ ): E =>
12
+ ({
13
+ ...e,
14
+ _etag: objectHash(e)
15
+ }) as any
16
+ export const makeUpdateETag = (name: string) =>
17
+ <E extends PersistenceModelType<Id>, Id extends string>(e: E, current: Opt<E>) =>
18
+ Effect.gen(function*($) {
19
+ if (current.isSome() && current.value._etag !== e._etag) {
20
+ return yield* $(
21
+ Effect.fail(new OptimisticConcurrencyException(name, current.value.id, current.value._etag, e._etag))
22
+ )
23
+ }
24
+ const newE = makeETag(e)
25
+ return newE
26
+ })
27
+
28
+ export function codeFilter<E extends { id: string }, NE extends E>(filter: Filter<NE>) {
29
+ return (x: E) =>
30
+ filter.type === "startsWith"
31
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
+ ? lowercaseIfString((x as any)[filter.by]).startsWith(filter.value.toLowerCase())
33
+ ? Opt(x as unknown as NE)
34
+ : Opt.none
35
+ : filter.type === "endsWith"
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ ? lowercaseIfString((x as any)[filter.by]).endsWith(filter.value.toLowerCase())
38
+ ? Opt(x as unknown as NE)
39
+ : Opt.none
40
+ : filter.type === "contains"
41
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
43
+ ? lowercaseIfString((x as any)[filter.by]).includes(filter.value.toLowerCase())
44
+ ? Opt(x as unknown as NE)
45
+ : Opt.none
46
+ : filter.type === "join_find"
47
+ ? filter.keys.some(k => {
48
+ const value = get(x, k) as Record<string, unknown>[]
49
+ // we mimic the behavior of cosmosdb; if the shape in db does not match what we're looking for, we imagine false hit
50
+ return (
51
+ value &&
52
+ value.some(v => compareCaseInsensitive(v[filter.valueKey], filter.value))
53
+ )
54
+ })
55
+ ? Opt(x as unknown as NE)
56
+ : Opt.none
57
+ : // TODO: support mixed or/and
58
+ filter.mode === "or"
59
+ ? filter.where
60
+ .some(p =>
61
+ p.t === "in"
62
+ ? p.value.includes(get(x, p.key))
63
+ : p.t === "not-in"
64
+ ? !p.value.includes(get(x, p.key))
65
+ : p.t === "not-eq"
66
+ ? !compareCaseInsensitive(get(x, p.key), p.value)
67
+ : compareCaseInsensitive(get(x, p.key), p.value)
68
+ )
69
+ ? Opt(x as unknown as NE)
70
+ : Opt.none
71
+ : filter.where
72
+ .every(p =>
73
+ p.t === "in"
74
+ ? p.value.includes(get(x, p.key))
75
+ : p.t === "not-in"
76
+ ? !p.value.includes(get(x, p.key))
77
+ : p.t === "not-eq"
78
+ ? p.key.includes(".-1.")
79
+ ? (get(x, p.key.split(".-1.")[0]) as any[])
80
+ // TODO: or vs and
81
+ .every(_ => !compareCaseInsensitive(get(_, p.key.split(".-1.")[1]!), p.value))
82
+ : !compareCaseInsensitive(get(x, p.key), p.value)
83
+ : p.key.includes(".-1.")
84
+ ? (get(x, p.key.split(".-1.")[0]) as any[])
85
+ // TODO: or vs and
86
+ .some(_ => compareCaseInsensitive(get(_, p.key.split(".-1.")[1]!), p.value))
87
+ : compareCaseInsensitive(get(x, p.key), p.value)
88
+ )
89
+ ? Opt(x as unknown as NE)
90
+ : Opt.none
91
+ }
92
+
93
+ export function codeFilterJoinSelect<E extends { id: string }, NE>(
94
+ filter: FilterJoinSelect
95
+ ) {
96
+ return (x: E) =>
97
+ filter.keys.filterMap(k => {
98
+ const value = get(x, k)
99
+ // we mimic the behavior of cosmosdb; if the shape in db does not match what we're looking for, we imagine false hit
100
+ return value
101
+ ? Opt(
102
+ (value as readonly NE[]).filterMap(v =>
103
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
104
+ compareCaseInsensitive((v as any)[filter.valueKey], filter.value)
105
+ ? Opt({ ...v, _rootId: x.id })
106
+ : Opt.none
107
+ )
108
+ )
109
+ : Opt.none
110
+ })
111
+ .flatMap(_ => _)
112
+ .toChunk
113
+ }
114
+
115
+ function lowercaseIfString<T>(val: T) {
116
+ if (typeof val === "string") {
117
+ return val.toLowerCase()
118
+ }
119
+ return val
120
+ }
121
+
122
+ function compareCaseInsensitive(valA: unknown, valB: unknown) {
123
+ return typeof valB === "string" && typeof valA === "string"
124
+ ? valA.toLowerCase() === valB.toLowerCase()
125
+ : valA === valB
126
+ }
@@ -0,0 +1 @@
1
+ export * from "./Store/service.js"
@@ -0,0 +1,30 @@
1
+ import { Queue as Q } from "@effect/io/Queue"
2
+
3
+ export interface MemQueue {
4
+ getOrCreateQueue: (k: string) => Effect<never, never, Queue<string>>
5
+ }
6
+
7
+ /**
8
+ * @tsplus type MemQueue.Ops
9
+ */
10
+
11
+ export interface MemQueueOps extends Tag<MemQueue> {}
12
+ export const MemQueue: MemQueueOps = Tag<MemQueue>()
13
+
14
+ /**
15
+ * @tsplus static MemQueue.Ops Live
16
+ */
17
+ export const LiveMemQueue = Effect.gen(function*($) {
18
+ const store = yield* $(Effect(new Map<string, Queue<string>>()))
19
+
20
+ return {
21
+ getOrCreateQueue: (k: string) =>
22
+ Effect.gen(function*($) {
23
+ const q = store.get(k)
24
+ if (q) return q
25
+ const newQ = yield* $(Q.unbounded<string>())
26
+ store.set(k, newQ)
27
+ return newQ
28
+ })
29
+ }
30
+ }).toLayer(MemQueue)