effect-app 4.0.0-beta.29 → 4.0.0-beta.290

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 (363) hide show
  1. package/CHANGELOG.md +1395 -0
  2. package/dist/Array.d.ts +2 -1
  3. package/dist/Array.d.ts.map +1 -1
  4. package/dist/Array.js +4 -4
  5. package/dist/Chunk.d.ts.map +1 -1
  6. package/dist/Config/SecretURL.d.ts +3 -1
  7. package/dist/Config/SecretURL.d.ts.map +1 -1
  8. package/dist/Config/SecretURL.js +3 -6
  9. package/dist/Config/internal/configSecretURL.d.ts.map +1 -1
  10. package/dist/Config/internal/configSecretURL.js +2 -2
  11. package/dist/Config.d.ts +2 -0
  12. package/dist/Config.d.ts.map +1 -0
  13. package/dist/Config.js +8 -0
  14. package/dist/ConfigProvider.d.ts +2 -0
  15. package/dist/ConfigProvider.d.ts.map +1 -0
  16. package/dist/ConfigProvider.js +6 -0
  17. package/dist/{ServiceMap.d.ts → Context.d.ts} +18 -20
  18. package/dist/Context.d.ts.map +1 -0
  19. package/dist/Context.js +67 -0
  20. package/dist/DataDependencies.d.ts +388 -0
  21. package/dist/DataDependencies.d.ts.map +1 -0
  22. package/dist/DataDependencies.js +64 -0
  23. package/dist/Effect.d.ts +10 -9
  24. package/dist/Effect.d.ts.map +1 -1
  25. package/dist/Effect.js +5 -8
  26. package/dist/Emailer.d.ts +51 -0
  27. package/dist/Emailer.d.ts.map +1 -0
  28. package/dist/Emailer.js +7 -0
  29. package/dist/Function.d.ts.map +1 -1
  30. package/dist/Layer.d.ts +10 -6
  31. package/dist/Layer.d.ts.map +1 -1
  32. package/dist/Layer.js +3 -2
  33. package/dist/Model/Repository/Registry.d.ts +22 -0
  34. package/dist/Model/Repository/Registry.d.ts.map +1 -0
  35. package/dist/Model/Repository/Registry.js +18 -0
  36. package/dist/Model/Repository/ext.d.ts +60 -0
  37. package/dist/Model/Repository/ext.d.ts.map +1 -0
  38. package/dist/Model/Repository/ext.js +122 -0
  39. package/dist/Model/Repository/internal/internal.d.ts +63 -0
  40. package/dist/Model/Repository/internal/internal.d.ts.map +1 -0
  41. package/dist/Model/Repository/internal/internal.js +438 -0
  42. package/dist/Model/Repository/legacy.d.ts +21 -0
  43. package/dist/Model/Repository/legacy.d.ts.map +1 -0
  44. package/dist/Model/Repository/legacy.js +2 -0
  45. package/dist/Model/Repository/makeRepo.d.ts +54 -0
  46. package/dist/Model/Repository/makeRepo.d.ts.map +1 -0
  47. package/dist/Model/Repository/makeRepo.js +27 -0
  48. package/dist/Model/Repository/service.d.ts +121 -0
  49. package/dist/Model/Repository/service.d.ts.map +1 -0
  50. package/dist/Model/Repository/service.js +2 -0
  51. package/dist/Model/Repository/validation.d.ts +58 -0
  52. package/dist/Model/Repository/validation.d.ts.map +1 -0
  53. package/dist/Model/Repository/validation.js +32 -0
  54. package/dist/Model/Repository.d.ts +7 -0
  55. package/dist/Model/Repository.d.ts.map +1 -0
  56. package/dist/Model/Repository.js +7 -0
  57. package/dist/Model/dsl.d.ts +33 -0
  58. package/dist/Model/dsl.d.ts.map +1 -0
  59. package/dist/Model/dsl.js +43 -0
  60. package/dist/Model/filter/filterApi.d.ts +30 -0
  61. package/dist/Model/filter/filterApi.d.ts.map +1 -0
  62. package/dist/Model/filter/filterApi.js +2 -0
  63. package/dist/Model/filter/types/errors.d.ts +29 -0
  64. package/dist/Model/filter/types/errors.d.ts.map +1 -0
  65. package/dist/Model/filter/types/errors.js +2 -0
  66. package/dist/Model/filter/types/fields.d.ts +15 -0
  67. package/dist/Model/filter/types/fields.d.ts.map +1 -0
  68. package/dist/Model/filter/types/fields.js +2 -0
  69. package/dist/Model/filter/types/path/common.d.ts +316 -0
  70. package/dist/Model/filter/types/path/common.d.ts.map +1 -0
  71. package/dist/Model/filter/types/path/common.js +2 -0
  72. package/dist/Model/filter/types/path/eager.d.ts +94 -0
  73. package/dist/Model/filter/types/path/eager.d.ts.map +1 -0
  74. package/dist/Model/filter/types/path/eager.js +36 -0
  75. package/dist/Model/filter/types/path/index.d.ts +4 -0
  76. package/dist/Model/filter/types/path/index.d.ts.map +1 -0
  77. package/dist/Model/filter/types/path/index.js +3 -0
  78. package/dist/Model/filter/types/utils.d.ts +79 -0
  79. package/dist/Model/filter/types/utils.d.ts.map +1 -0
  80. package/dist/Model/filter/types/utils.js +2 -0
  81. package/dist/Model/filter/types/validator.d.ts +30 -0
  82. package/dist/Model/filter/types/validator.d.ts.map +1 -0
  83. package/dist/Model/filter/types/validator.js +2 -0
  84. package/dist/Model/filter/types.d.ts +5 -0
  85. package/dist/Model/filter/types.d.ts.map +1 -0
  86. package/dist/Model/filter/types.js +7 -0
  87. package/dist/Model/query/dsl.d.ts +506 -0
  88. package/dist/Model/query/dsl.d.ts.map +1 -0
  89. package/dist/Model/query/dsl.js +376 -0
  90. package/dist/Model/query/new-kid-interpreter.d.ts +136 -0
  91. package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -0
  92. package/dist/Model/query/new-kid-interpreter.js +336 -0
  93. package/dist/Model/query.d.ts +15 -0
  94. package/dist/Model/query.d.ts.map +1 -0
  95. package/dist/Model/query.js +3 -0
  96. package/dist/Model.d.ts +5 -0
  97. package/dist/Model.d.ts.map +1 -0
  98. package/dist/Model.js +5 -0
  99. package/dist/NonEmptySet.d.ts +3 -1
  100. package/dist/NonEmptySet.d.ts.map +1 -1
  101. package/dist/NonEmptySet.js +2 -2
  102. package/dist/Option.d.ts +1 -0
  103. package/dist/Option.d.ts.map +1 -1
  104. package/dist/Option.js +3 -1
  105. package/dist/Pure.d.ts +7 -5
  106. package/dist/Pure.d.ts.map +1 -1
  107. package/dist/Pure.js +7 -4
  108. package/dist/QueueMaker.d.ts +11 -0
  109. package/dist/QueueMaker.d.ts.map +1 -0
  110. package/dist/QueueMaker.js +11 -0
  111. package/dist/RequestContext.d.ts +87 -0
  112. package/dist/RequestContext.d.ts.map +1 -0
  113. package/dist/RequestContext.js +45 -0
  114. package/dist/RequestScopedDependencies.d.ts +21 -0
  115. package/dist/RequestScopedDependencies.d.ts.map +1 -0
  116. package/dist/RequestScopedDependencies.js +16 -0
  117. package/dist/Schema/Class.d.ts +188 -19
  118. package/dist/Schema/Class.d.ts.map +1 -1
  119. package/dist/Schema/Class.js +260 -17
  120. package/dist/Schema/FastCheck.d.ts.map +1 -1
  121. package/dist/Schema/SchemaParser.d.ts +5 -0
  122. package/dist/Schema/SchemaParser.d.ts.map +1 -0
  123. package/dist/Schema/SchemaParser.js +6 -0
  124. package/dist/Schema/SpecialJsonSchema.d.ts +34 -0
  125. package/dist/Schema/SpecialJsonSchema.d.ts.map +1 -0
  126. package/dist/Schema/SpecialJsonSchema.js +118 -0
  127. package/dist/Schema/SpecialOpenApi.d.ts +32 -0
  128. package/dist/Schema/SpecialOpenApi.d.ts.map +1 -0
  129. package/dist/Schema/SpecialOpenApi.js +123 -0
  130. package/dist/Schema/brand.d.ts +4 -2
  131. package/dist/Schema/brand.d.ts.map +1 -1
  132. package/dist/Schema/brand.js +3 -1
  133. package/dist/Schema/email.d.ts.map +1 -1
  134. package/dist/Schema/email.js +7 -4
  135. package/dist/Schema/ext.d.ts +338 -55
  136. package/dist/Schema/ext.d.ts.map +1 -1
  137. package/dist/Schema/ext.js +358 -53
  138. package/dist/Schema/moreStrings.d.ts +82 -36
  139. package/dist/Schema/moreStrings.d.ts.map +1 -1
  140. package/dist/Schema/moreStrings.js +49 -42
  141. package/dist/Schema/numbers.d.ts +34 -21
  142. package/dist/Schema/numbers.d.ts.map +1 -1
  143. package/dist/Schema/numbers.js +55 -12
  144. package/dist/Schema/phoneNumber.d.ts.map +1 -1
  145. package/dist/Schema/phoneNumber.js +6 -3
  146. package/dist/Schema/schema.d.ts +1 -1
  147. package/dist/Schema/schema.d.ts.map +1 -1
  148. package/dist/Schema/schema.js +2 -2
  149. package/dist/Schema/strings.d.ts +18 -4
  150. package/dist/Schema/strings.d.ts.map +1 -1
  151. package/dist/Schema/strings.js +1 -5
  152. package/dist/Schema.d.ts +222 -8
  153. package/dist/Schema.d.ts.map +1 -1
  154. package/dist/Schema.js +191 -12
  155. package/dist/SchemaAST.d.ts +2 -0
  156. package/dist/SchemaAST.d.ts.map +1 -0
  157. package/dist/SchemaAST.js +2 -0
  158. package/dist/Set.d.ts +4 -1
  159. package/dist/Set.d.ts.map +1 -1
  160. package/dist/Set.js +3 -2
  161. package/dist/Store.d.ts +163 -0
  162. package/dist/Store.d.ts.map +1 -0
  163. package/dist/Store.js +113 -0
  164. package/dist/_ext/Array.d.ts +1 -1
  165. package/dist/_ext/Array.d.ts.map +1 -1
  166. package/dist/_ext/Array.js +4 -2
  167. package/dist/_ext/misc.d.ts +4 -1
  168. package/dist/_ext/misc.d.ts.map +1 -1
  169. package/dist/_ext/misc.js +4 -2
  170. package/dist/_ext/ord.ext.d.ts +2 -1
  171. package/dist/_ext/ord.ext.d.ts.map +1 -1
  172. package/dist/_ext/ord.ext.js +2 -2
  173. package/dist/builtin.d.ts +2 -14
  174. package/dist/builtin.d.ts.map +1 -1
  175. package/dist/builtin.js +1 -1
  176. package/dist/client/InvalidationKeys.d.ts +29 -0
  177. package/dist/client/InvalidationKeys.d.ts.map +1 -0
  178. package/dist/client/InvalidationKeys.js +33 -0
  179. package/dist/client/apiClientFactory.d.ts +19 -31
  180. package/dist/client/apiClientFactory.d.ts.map +1 -1
  181. package/dist/client/apiClientFactory.js +155 -35
  182. package/dist/client/clientFor.d.ts +54 -18
  183. package/dist/client/clientFor.d.ts.map +1 -1
  184. package/dist/client/clientFor.js +9 -1
  185. package/dist/client/errors.d.ts +82 -27
  186. package/dist/client/errors.d.ts.map +1 -1
  187. package/dist/client/errors.js +75 -19
  188. package/dist/client/makeClient.d.ts +492 -32
  189. package/dist/client/makeClient.d.ts.map +1 -1
  190. package/dist/client/makeClient.js +62 -28
  191. package/dist/client.d.ts +2 -0
  192. package/dist/client.d.ts.map +1 -1
  193. package/dist/client.js +3 -1
  194. package/dist/faker.d.ts.map +1 -1
  195. package/dist/http/Request.d.ts +1 -1
  196. package/dist/http/Request.d.ts.map +1 -1
  197. package/dist/http/Request.js +2 -2
  198. package/dist/ids.d.ts +42 -14
  199. package/dist/ids.d.ts.map +1 -1
  200. package/dist/ids.js +30 -5
  201. package/dist/index.d.ts +6 -7
  202. package/dist/index.d.ts.map +1 -1
  203. package/dist/index.js +8 -8
  204. package/dist/middleware.d.ts +13 -7
  205. package/dist/middleware.d.ts.map +1 -1
  206. package/dist/middleware.js +14 -8
  207. package/dist/rpc/Invalidation.d.ts +3140 -0
  208. package/dist/rpc/Invalidation.d.ts.map +1 -0
  209. package/dist/rpc/Invalidation.js +178 -0
  210. package/dist/rpc/MiddlewareMaker.d.ts +11 -7
  211. package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
  212. package/dist/rpc/MiddlewareMaker.js +59 -38
  213. package/dist/rpc/RpcContextMap.d.ts +3 -3
  214. package/dist/rpc/RpcContextMap.d.ts.map +1 -1
  215. package/dist/rpc/RpcContextMap.js +4 -4
  216. package/dist/rpc/RpcMiddleware.d.ts +14 -10
  217. package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
  218. package/dist/rpc/RpcMiddleware.js +1 -1
  219. package/dist/rpc.d.ts +1 -1
  220. package/dist/rpc.d.ts.map +1 -1
  221. package/dist/rpc.js +2 -2
  222. package/dist/runtime.d.ts +19 -0
  223. package/dist/runtime.d.ts.map +1 -0
  224. package/dist/runtime.js +40 -0
  225. package/dist/setupRequest.d.ts +20 -0
  226. package/dist/setupRequest.d.ts.map +1 -0
  227. package/dist/setupRequest.js +72 -0
  228. package/dist/toast.d.ts +51 -0
  229. package/dist/toast.d.ts.map +1 -0
  230. package/dist/toast.js +34 -0
  231. package/dist/transform.d.ts +1 -1
  232. package/dist/transform.d.ts.map +1 -1
  233. package/dist/transform.js +4 -5
  234. package/dist/utils/effectify.d.ts +1 -1
  235. package/dist/utils/effectify.d.ts.map +1 -1
  236. package/dist/utils/effectify.js +2 -2
  237. package/dist/utils/extend.d.ts.map +1 -1
  238. package/dist/utils/gen.d.ts +4 -4
  239. package/dist/utils/gen.d.ts.map +1 -1
  240. package/dist/utils/logLevel.d.ts +2 -2
  241. package/dist/utils/logLevel.d.ts.map +1 -1
  242. package/dist/utils/logger.d.ts +4 -3
  243. package/dist/utils/logger.d.ts.map +1 -1
  244. package/dist/utils/logger.js +4 -4
  245. package/dist/utils.d.ts +34 -39
  246. package/dist/utils.d.ts.map +1 -1
  247. package/dist/utils.js +33 -37
  248. package/dist/validation/validators.d.ts.map +1 -1
  249. package/dist/validation.d.ts.map +1 -1
  250. package/dist/withToast.d.ts +30 -0
  251. package/dist/withToast.d.ts.map +1 -0
  252. package/dist/withToast.js +64 -0
  253. package/package.json +22 -251
  254. package/src/Array.ts +5 -5
  255. package/src/Chunk.ts +3 -3
  256. package/src/Config/SecretURL.ts +6 -3
  257. package/src/Config/internal/configSecretURL.ts +2 -2
  258. package/src/Config.ts +7 -0
  259. package/src/ConfigProvider.ts +5 -0
  260. package/src/{ServiceMap.ts → Context.ts} +56 -63
  261. package/src/DataDependencies.ts +114 -0
  262. package/src/Effect.ts +14 -16
  263. package/src/Emailer.ts +51 -0
  264. package/src/Inputify.type.ts +1 -1
  265. package/src/Layer.ts +11 -7
  266. package/src/Model/Repository/Registry.ts +35 -0
  267. package/src/Model/Repository/ext.ts +375 -0
  268. package/src/Model/Repository/internal/internal.ts +755 -0
  269. package/src/Model/Repository/legacy.ts +29 -0
  270. package/src/Model/Repository/makeRepo.ts +145 -0
  271. package/src/Model/Repository/service.ts +676 -0
  272. package/src/Model/Repository/validation.ts +31 -0
  273. package/src/Model/Repository.ts +6 -0
  274. package/src/Model/dsl.ts +129 -0
  275. package/src/Model/filter/filterApi.ts +60 -0
  276. package/src/Model/filter/types/errors.ts +47 -0
  277. package/src/Model/filter/types/fields.ts +50 -0
  278. package/src/Model/filter/types/path/common.ts +404 -0
  279. package/src/Model/filter/types/path/eager.ts +329 -0
  280. package/src/Model/filter/types/path/index.ts +4 -0
  281. package/src/Model/filter/types/utils.ts +128 -0
  282. package/src/Model/filter/types/validator.ts +46 -0
  283. package/src/Model/filter/types.ts +6 -0
  284. package/src/Model/query/dsl.ts +2781 -0
  285. package/src/Model/query/new-kid-interpreter.ts +484 -0
  286. package/src/Model/query.ts +13 -0
  287. package/src/Model.ts +4 -0
  288. package/src/NonEmptySet.ts +6 -4
  289. package/src/Option.ts +2 -0
  290. package/src/Pure.ts +10 -7
  291. package/src/QueueMaker.ts +11 -0
  292. package/src/RequestContext.ts +48 -0
  293. package/src/RequestScopedDependencies.ts +45 -0
  294. package/src/Schema/Class.ts +633 -59
  295. package/src/Schema/SchemaParser.ts +12 -0
  296. package/src/Schema/SpecialJsonSchema.ts +139 -0
  297. package/src/Schema/SpecialOpenApi.ts +130 -0
  298. package/src/Schema/brand.ts +22 -2
  299. package/src/Schema/email.ts +9 -4
  300. package/src/Schema/ext.ts +446 -91
  301. package/src/Schema/moreStrings.ts +147 -68
  302. package/src/Schema/numbers.ts +97 -28
  303. package/src/Schema/phoneNumber.ts +9 -5
  304. package/src/Schema/schema.ts +1 -1
  305. package/src/Schema/strings.ts +23 -14
  306. package/src/Schema.ts +397 -26
  307. package/src/SchemaAST.ts +1 -0
  308. package/src/Set.ts +6 -2
  309. package/src/Store.ts +273 -0
  310. package/src/_ext/Array.ts +4 -2
  311. package/src/_ext/misc.ts +4 -1
  312. package/src/_ext/ord.ext.ts +2 -1
  313. package/src/builtin-json.d.ts +24 -0
  314. package/src/builtin.ts +16 -21
  315. package/src/client/InvalidationKeys.ts +50 -0
  316. package/src/client/apiClientFactory.ts +299 -134
  317. package/src/client/clientFor.ts +107 -34
  318. package/src/client/errors.ts +100 -29
  319. package/src/client/makeClient.ts +586 -78
  320. package/src/client.ts +6 -4
  321. package/src/http/Request.ts +3 -3
  322. package/src/http.ts +1 -1
  323. package/src/ids.ts +33 -6
  324. package/src/index.ts +20 -23
  325. package/src/middleware.ts +13 -9
  326. package/src/rpc/Invalidation.ts +278 -0
  327. package/src/rpc/MiddlewareMaker.ts +88 -80
  328. package/src/rpc/README.md +2 -2
  329. package/src/rpc/RpcContextMap.ts +7 -6
  330. package/src/rpc/RpcMiddleware.ts +19 -13
  331. package/src/rpc.ts +4 -4
  332. package/src/runtime.ts +56 -0
  333. package/src/setupRequest.ts +138 -0
  334. package/src/toast.ts +54 -0
  335. package/src/transform.ts +4 -4
  336. package/src/utils/effectify.ts +1 -1
  337. package/src/utils/gen.ts +8 -8
  338. package/src/utils/logLevel.ts +1 -1
  339. package/src/utils/logger.ts +4 -3
  340. package/src/utils.ts +85 -158
  341. package/src/validation.ts +2 -2
  342. package/src/withToast.ts +133 -0
  343. package/test/dist/rpc.test.d.ts.map +1 -1
  344. package/test/dist/secretURL.test.d.ts.map +1 -0
  345. package/test/dist/special.test.d.ts.map +1 -0
  346. package/test/moreStrings.test.ts +1 -1
  347. package/test/rpc.test.ts +45 -6
  348. package/test/schema.test.ts +459 -30
  349. package/test/secretURL.test.ts +160 -0
  350. package/test/special.test.ts +1258 -0
  351. package/test/utils.test.ts +7 -7
  352. package/tsconfig.base.json +6 -5
  353. package/tsconfig.json +3 -1
  354. package/tsconfig.src.json +29 -29
  355. package/tsconfig.test.json +2 -2
  356. package/dist/Operations.d.ts +0 -123
  357. package/dist/Operations.d.ts.map +0 -1
  358. package/dist/Operations.js +0 -29
  359. package/dist/ServiceMap.d.ts.map +0 -1
  360. package/dist/ServiceMap.js +0 -91
  361. package/eslint.config.mjs +0 -26
  362. package/src/Operations.ts +0 -55
  363. package/tsconfig.json.bak +0 -12
package/src/client.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  // codegen:start {preset: barrel, include: ./client/*.ts}
2
- export * from "./client/apiClientFactory.js"
3
- export * from "./client/clientFor.js"
4
- export * from "./client/errors.js"
5
- export * from "./client/makeClient.js"
2
+ export * from "./client/apiClientFactory.ts"
3
+ export * from "./client/clientFor.ts"
4
+ export * from "./client/errors.ts"
5
+ export * from "./client/InvalidationKeys.ts"
6
+ export * from "./client/makeClient.ts"
6
7
  // codegen:end
8
+ export * as DataDependencies from "./DataDependencies.ts"
@@ -1,7 +1,7 @@
1
- import { Option } from "effect"
1
+ import * as Option from "effect/Option"
2
2
  import type { HttpClientResponse } from "effect/unstable/http/HttpClientResponse"
3
- import * as Effect from "../Effect.js"
4
- import { HttpClient, HttpClientError, HttpClientRequest, HttpHeaders } from "./internal/lib.js"
3
+ import * as Effect from "../Effect.ts"
4
+ import { HttpClient, HttpClientError, HttpClientRequest, HttpHeaders } from "./internal/lib.ts"
5
5
 
6
6
  export interface ResponseWithBody<A> extends Pick<HttpClientResponse, "headers" | "status" | "remoteAddress"> {
7
7
  readonly body: A
package/src/http.ts CHANGED
@@ -1 +1 @@
1
- export * from "./http/internal/lib.js"
1
+ export * from "./http/internal/lib.ts"
package/src/ids.ts CHANGED
@@ -1,28 +1,55 @@
1
1
  import { brandedStringId, type Codec, NonEmptyString255, StringId, type StringIdBrand, withDefaultMake } from "effect-app/Schema"
2
2
  import type { B } from "effect-app/Schema/schema"
3
+ import * as Effect from "effect/Effect"
3
4
  import type { Simplify } from "effect/Types"
4
- import { S } from "./index.js"
5
- import { extendM } from "./utils.js"
5
+ import * as S from "./Schema.ts"
6
+ import { extendM } from "./utils.ts"
6
7
 
7
8
  export interface RequestIdBrand extends StringIdBrand {
8
9
  readonly RequestId: unique symbol
9
10
  }
10
11
 
11
12
  export type RequestId = NonEmptyString255
12
- // a request id may be made from a span id, which does not comply with StringId schema.
13
+ /**
14
+ * Schema for a request id.
15
+ *
16
+ * A request id may be made from a span id, which does not comply with the
17
+ * `StringId` schema (hence the looser `NonEmptyString255` base).
18
+ *
19
+ * `.withConstructorDefault` => fresh `StringId` (construction-only; not
20
+ * applied during decode — cannot be used to JIT-migrate database fields).
21
+ * See `./Schema/ext.ts` for the full policy note.
22
+ */
13
23
  export const RequestId = extendM(
14
24
  Object
15
25
  .assign(Object.create(NonEmptyString255) as {}, NonEmptyString255 as unknown as Codec<NonEmptyString255, string>),
16
26
  (s) => {
17
- const make = StringId.make as () => NonEmptyString255
27
+ function make(): NonEmptyString255
28
+ function make(input: string, options?: S.MakeOptions): NonEmptyString255
29
+ function make(input?: string, options?: S.MakeOptions): NonEmptyString255 {
30
+ const id = input === undefined ? StringId.make() : StringId.make(input, options)
31
+ return id as NonEmptyString255
32
+ }
18
33
  return ({
19
34
  make,
20
- withDefault: s.pipe(S.withDefaultConstructor(make))
35
+ /**
36
+ * Construction-only default: fresh `StringId`. Applied only when the
37
+ * field is omitted from `.make(...)` input. NOT applied during decode —
38
+ * cannot be used to JIT-migrate database fields. See `./Schema/ext.ts`
39
+ * file-level note.
40
+ */
41
+ withConstructorDefault: S.withConstructorDefault(Effect.sync(make))(s as typeof s & S.WithoutConstructorDefault)
21
42
  })
22
43
  }
23
44
  )
24
45
  .pipe(withDefaultMake)
25
46
 
26
47
  export interface UserProfileIdBrand extends Simplify<B.Brand<"UserProfileId"> & StringIdBrand> {}
27
- export type UserProfileId = StringId & UserProfileIdBrand
48
+ export type UserProfileId = string & UserProfileIdBrand
49
+ /**
50
+ * Branded `StringId` for user profiles.
51
+ *
52
+ * Exposes `.withConstructorDefault` (fresh id) — construction-only; not
53
+ * applied during decode. See `./Schema/ext.ts` for the full policy note.
54
+ */
28
55
  export const UserProfileId = brandedStringId<UserProfileId>()
package/src/index.ts CHANGED
@@ -1,30 +1,27 @@
1
- import "./builtin.js"
1
+ // eslint-disable-next-line import/no-unassigned-import
2
+ import "./builtin.ts"
2
3
 
3
- import * as ServiceMap from "./ServiceMap.js"
4
+ export * as Fnc from "./Function.ts"
5
+ export * as Utils from "./utils.ts"
4
6
 
5
- export * as Fnc from "./Function.js"
6
- export * as Utils from "./utils.js"
7
+ export * as Array from "./Array.ts"
8
+ export * as Config from "./Config.ts"
9
+ export * as ConfigProvider from "./ConfigProvider.ts"
10
+ export * as Context from "./Context.ts"
11
+ export * as Effect from "./Effect.ts"
12
+ export * as Layer from "./Layer.ts"
13
+ export * as Model from "./Model.ts"
14
+ export * as NonEmptySet from "./NonEmptySet.ts"
15
+ export * as Set from "./Set.ts"
16
+ export * as Store from "./Store.ts"
7
17
 
8
- export * as Array from "./Array.js"
9
- export * as Effect from "./Effect.js"
10
- export * as Layer from "./Layer.js"
11
- export * as NonEmptySet from "./NonEmptySet.js"
12
- export * as ServiceMap from "./ServiceMap.js"
13
- export * as Set from "./Set.js"
14
-
15
- export {
16
- /**
17
- * @deprecated use ServiceMap directly instead
18
- */
19
- ServiceMap as Context
20
- }
21
-
22
- export { type NonEmptyArray, type NonEmptyReadonlyArray } from "./Array.js"
18
+ export { type NonEmptyArray, type NonEmptyReadonlyArray } from "./Array.ts"
23
19
 
24
20
  export * from "effect"
25
21
 
26
- export type * as Types from "./Types.js"
22
+ export type * as Types from "./Types.ts"
27
23
 
28
- export * as SecretURL from "./Config/SecretURL.js"
29
- export * as S from "./Schema.js"
30
- export { copy } from "./utils.js"
24
+ export * as SecretURL from "./Config/SecretURL.ts"
25
+ export * as RpcX from "./rpc.ts"
26
+ export * as S from "./Schema.ts"
27
+ export { copy } from "./utils.ts"
package/src/middleware.ts CHANGED
@@ -1,21 +1,25 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { ServiceMap } from "effect-app"
3
- import { RpcX } from "./rpc.js"
2
+ import * as Context from "effect-app/Context"
3
+ import { RpcMiddleware } from "./rpc.ts"
4
4
 
5
- export class DevMode extends ServiceMap.Reference("DevMode", { defaultValue: () => false }) {}
5
+ export class DevMode extends Context.Reference("DevMode", { defaultValue: () => false }) {}
6
6
 
7
- export class RequestCacheMiddleware
8
- extends RpcX.RpcMiddleware.Tag<RequestCacheMiddleware>()("RequestCacheMiddleware")
9
- {}
7
+ export class RequestCacheMiddleware extends RpcMiddleware.Tag<RequestCacheMiddleware>()("RequestCacheMiddleware") {}
10
8
 
11
9
  export class ConfigureInterruptibilityMiddleware
12
- extends RpcX.RpcMiddleware.Tag<ConfigureInterruptibilityMiddleware>()("ConfigureInterruptibilityMiddleware")
10
+ extends RpcMiddleware.Tag<ConfigureInterruptibilityMiddleware>()("ConfigureInterruptibilityMiddleware")
13
11
  {}
14
12
 
15
- export class LoggerMiddleware extends RpcX.RpcMiddleware.Tag<LoggerMiddleware>()("LoggerMiddleware") {}
13
+ export class LoggerMiddleware extends RpcMiddleware.Tag<LoggerMiddleware>()("LoggerMiddleware") {}
16
14
 
17
- export class DevModeMiddleware extends RpcX.RpcMiddleware.Tag<DevModeMiddleware>()("DevModeMiddleware") {}
15
+ export class DevModeMiddleware extends RpcMiddleware.Tag<DevModeMiddleware>()("DevModeMiddleware") {}
18
16
 
17
+ /**
18
+ * Generic middlewares attached by `makeRouter` to every request.
19
+ *
20
+ * Invalidation key wrap/unwrap is handled by the routing layer (server) and the
21
+ * api client factory (client) directly — there is no middleware tag for it.
22
+ */
19
23
  export const DefaultGenericMiddlewares = [
20
24
  RequestCacheMiddleware,
21
25
  ConfigureInterruptibilityMiddleware,
@@ -0,0 +1,278 @@
1
+ import * as Ref from "effect/Ref"
2
+ import { Rpc } from "effect/unstable/rpc"
3
+ import { type ClientForOptions, makeQueryKey } from "../client/clientFor.ts"
4
+ import * as Context from "../Context.ts"
5
+ import * as DataDependencies from "../DataDependencies.ts"
6
+ import * as Effect from "../Effect.ts"
7
+ import * as S from "../Schema.ts"
8
+
9
+ /**
10
+ * Shorthand for a handler-derived invalidation key.
11
+ * Accepts an RPC handler object so `add(GetMe)` is equivalent to
12
+ * `add(makeQueryKey(GetMe))`.
13
+ */
14
+ export type InvalidationKeyInput = InvalidationKey | { readonly id: string; readonly options?: ClientForOptions }
15
+
16
+ const normalizeKey = (input: InvalidationKeyInput): InvalidationKey => {
17
+ if (Array.isArray(input)) return input
18
+ const handler = input as { id: string; options?: ClientForOptions }
19
+ return makeQueryKey(handler.options ? { id: handler.id, options: handler.options } : { id: handler.id })
20
+ }
21
+
22
+ // Disambiguates `add` overloads: a `string[]` means a single key; an array
23
+ // containing arrays-or-objects means a batch of inputs.
24
+ const isBatch = (
25
+ input: InvalidationKeyInput | ReadonlyArray<InvalidationKeyInput>
26
+ ): input is ReadonlyArray<InvalidationKeyInput> =>
27
+ Array.isArray(input) && input[0] !== undefined && typeof input[0] !== "string"
28
+
29
+ const normalizeInputs = (
30
+ input: InvalidationKeyInput | ReadonlyArray<InvalidationKeyInput>
31
+ ): ReadonlyArray<InvalidationKey> => isBatch(input) ? input.map(normalizeKey) : [normalizeKey(input)]
32
+
33
+ /**
34
+ * A single segment within an `InvalidationKey` array.
35
+ * Accepts any JSON-compatible value: string, number, boolean, null,
36
+ * arrays and objects recursively — matching TanStack Query's `queryKey` element type.
37
+ */
38
+ export const InvalidationKeySegment = S.Json
39
+ export type InvalidationKeySegment = S.Schema.Type<typeof InvalidationKeySegment>
40
+
41
+ /** Schema for a single invalidation key – an array of segments compatible with TanStack Query `queryKey`. */
42
+ export const InvalidationKey = S.Array(InvalidationKeySegment)
43
+ export type InvalidationKey = S.Schema.Type<typeof InvalidationKey>
44
+
45
+ /** Schema for the full set of invalidation keys – an array of `InvalidationKey`. */
46
+ export const InvalidationKeys = S.Array(InvalidationKey)
47
+ export type InvalidationKeys = S.Schema.Type<typeof InvalidationKeys>
48
+
49
+ /** Metadata included in every command response for server-driven cache invalidation. */
50
+ export const CommandMetaData = S.Struct({
51
+ invalidateQueries: InvalidationKeys,
52
+ dataDependencies: DataDependencies.DataDependencySet
53
+ })
54
+ export type CommandMetaData = S.Schema.Type<typeof CommandMetaData>
55
+
56
+ export const emptyDataDependencies: DataDependencies.DataDependencySet = {
57
+ reads: DataDependencies.empty(),
58
+ writes: DataDependencies.empty()
59
+ }
60
+
61
+ export const makeMetaData = (
62
+ invalidateQueries: InvalidationKeys,
63
+ dataDependencies: DataDependencies.DataDependencySet = emptyDataDependencies
64
+ ): CommandMetaData => ({ invalidateQueries, dataDependencies })
65
+
66
+ export const QueryResponseWithMetaData = <S extends S.Top>(success: S) =>
67
+ S.Struct({ payload: success, metadata: S.Struct({ dataDependencies: DataDependencies.DataDependencySet }) })
68
+
69
+ /**
70
+ * Wraps a command's success schema so that the wire format carries both the `payload`
71
+ * (the handler's actual return value) and `metadata` (server-driven cache invalidation keys).
72
+ * Transparent to users: the server handler returns the plain payload and the client receives
73
+ * the plain payload — wrapping/unwrapping is handled internally by the routing layer.
74
+ */
75
+ export const CommandResponseWithMetaData = <S extends S.Top>(success: S) =>
76
+ S.Struct({ payload: success, metadata: CommandMetaData })
77
+
78
+ /**
79
+ * Wraps a command's failure schema so that the wire format carries both the `error`
80
+ * (the handler's actual failure value) and `metadata` (server-driven cache invalidation keys
81
+ * accumulated thus far before the failure occurred).
82
+ * Transparent to users: the server handler fails with the plain error and the client receives
83
+ * the plain error — wrapping/unwrapping is handled internally by the routing layer.
84
+ */
85
+ export const CommandFailureWithMetaData = <E extends S.Top>(error: E) =>
86
+ S.Struct({ _tag: S.Literal("CommandFailureWithMetaData"), error, metadata: CommandMetaData })
87
+
88
+ /**
89
+ * Stream chunk schema for stream responses with metadata.
90
+ * Each item is either a data value, an intermediate "metadata" signal carrying cache
91
+ * invalidation keys accumulated since the previous drain, or a final "done" signal.
92
+ * Transparent to users: stream handlers return plain values and clients receive plain values —
93
+ * wrapping/unwrapping is handled internally by the routing layer.
94
+ *
95
+ * The "done" chunk is always the last item in the stream and carries any remaining invalidation
96
+ * keys. An optional "metadata" chunk may appear after any "value" chunk and carries keys
97
+ * accumulated since the last drain (V3: mid-stream invalidation).
98
+ */
99
+ export const StreamResponseChunk = <S extends S.Top>(success: S) =>
100
+ S.Union([
101
+ S.Struct({ _tag: S.Literal("value"), value: success }),
102
+ S.Struct({ _tag: S.Literal("metadata"), metadata: CommandMetaData }),
103
+ S.Struct({ _tag: S.Literal("done"), metadata: CommandMetaData })
104
+ ])
105
+
106
+ export type StreamResponseChunk<A> =
107
+ | { readonly _tag: "value"; readonly value: A }
108
+ | { readonly _tag: "metadata"; readonly metadata: CommandMetaData }
109
+ | { readonly _tag: "done"; readonly metadata: CommandMetaData }
110
+
111
+ /**
112
+ * Stream chunk schema for stream failures with metadata.
113
+ * Used to signal a stream failure while still carrying cache invalidation keys
114
+ * accumulated thus far.
115
+ */
116
+ export const StreamFailureChunk = <E extends S.Top>(error: E) =>
117
+ S.Struct({ _tag: S.Literal("error"), error, metadata: CommandMetaData })
118
+
119
+ export type StreamFailureChunk<E> = { readonly _tag: "error"; readonly error: E; readonly metadata: CommandMetaData }
120
+
121
+ /**
122
+ * Context annotation for declaring static cache invalidation keys on a low-level `Rpc` definition.
123
+ * These keys are always included in the command response metadata, regardless of the handler logic.
124
+ *
125
+ * Prefer using `makeQueryKey` over raw string arrays to stay in sync with the actual query
126
+ * definitions without manual string maintenance:
127
+ *
128
+ * ```ts
129
+ * import { makeQueryKey } from "effect-app/client"
130
+ * import { Invalidation } from "effect-app/rpc"
131
+ * import * as UserRsc from "../User/index.ts" // separate module to avoid circular deps
132
+ *
133
+ * class UpdateProfile extends Rpc.make("UpdateProfile", { ... })
134
+ * .annotate(Invalidation.Invalidates, [makeQueryKey(UserRsc.GetMe), makeQueryKey(UserRsc.GetProfile)]) {}
135
+ * ```
136
+ *
137
+ * **Circular dependency note:** if mutations and queries live in the same file you may hit a
138
+ * circular reference at evaluation time. The idiomatic fix is to move mutations into their own
139
+ * module (e.g. `User/mutations.ts`) that directly imports the relevant query classes rather than
140
+ * re-exporting them through a barrel.
141
+ *
142
+ * For the higher-level `Command`/`Query` builders from `makeRpcClient`, use the
143
+ * `invalidatesQueries` callback argument instead (it receives the same query keys at runtime).
144
+ */
145
+ export const Invalidates = Context.Reference<ReadonlyArray<InvalidationKey>>(
146
+ "effect-app/rpc/Invalidates",
147
+ { defaultValue: () => [] }
148
+ )
149
+ export type Invalidates = typeof Invalidates
150
+
151
+ /** The shape of the per-request service that accumulates invalidation keys. */
152
+ export interface InvalidationSetService {
153
+ readonly add: (
154
+ input: InvalidationKeyInput | ReadonlyArray<InvalidationKeyInput>
155
+ ) => Effect.Effect<void>
156
+ readonly get: Effect.Effect<ReadonlyArray<InvalidationKey>>
157
+ /**
158
+ * V3: Reads all currently accumulated keys and resets the bucket to empty.
159
+ * Used by the stream routing layer to emit intermediate "metadata" chunks
160
+ * without re-sending keys that have already been forwarded to the client.
161
+ */
162
+ readonly drain: Effect.Effect<ReadonlyArray<InvalidationKey>>
163
+ }
164
+
165
+ /**
166
+ * Request-scoped service for accumulating invalidation keys dynamically inside a handler.
167
+ * Provided by `InvalidationMiddlewareLive` for every RPC call; has a no-op default so it is
168
+ * safe to use even when the HTTP middleware is absent (tests, workers, etc.).
169
+ *
170
+ * Use `InvalidationSet.add(key)` as a shorthand to skip `.use(_ => _.add(key))`. The
171
+ * underlying service is still available via `.use` / `.useSync` for advanced cases.
172
+ *
173
+ * `add` accepts an RPC handler directly (e.g. `UserRsc.GetMe`) — its query key is derived via
174
+ * `makeQueryKey` so keys stay in sync with the actual query definitions. Raw `InvalidationKey`
175
+ * arrays and arrays of either form are also accepted.
176
+ *
177
+ * ```ts
178
+ * import * as Effect from "effect/Effect"
179
+ * import { Invalidation } from "effect-app/rpc"
180
+ * import * as CartRsc from "../Cart/queries.ts"
181
+ * import * as UserRsc from "../User/queries.ts"
182
+ *
183
+ * const handler = Effect.fnUntraced(function*(req: UpdateCartRequest) {
184
+ * const cart = yield* CartRepo.save(req.cart)
185
+ *
186
+ * // single handler
187
+ * yield* Invalidation.InvalidationSet.add(UserRsc.GetMe)
188
+ *
189
+ * // batch
190
+ * if (cart.isCheckedOut) {
191
+ * yield* Invalidation.InvalidationSet.add([CartRsc.GetCartStats, UserRsc.GetMe])
192
+ * }
193
+ *
194
+ * return cart
195
+ * })
196
+ * ```
197
+ *
198
+ * You can combine static (`Invalidates` annotation) and dynamic (`InvalidationSet.use`) keys:
199
+ * the annotation pre-populates the set before the handler runs; dynamic additions accumulate
200
+ * throughout the handler. All keys are included in the command response metadata.
201
+ */
202
+ const InvalidationSetRef = Context.Reference<InvalidationSetService>(
203
+ "effect-app/rpc/InvalidationSet",
204
+ {
205
+ defaultValue: () => ({
206
+ add: (_input: InvalidationKeyInput | ReadonlyArray<InvalidationKeyInput>) => Effect.void,
207
+ get: Effect.succeed([] as ReadonlyArray<InvalidationKey>),
208
+ drain: Effect.succeed([] as ReadonlyArray<InvalidationKey>)
209
+ })
210
+ }
211
+ )
212
+ export const InvalidationSet = Object.assign(InvalidationSetRef, {
213
+ /**
214
+ * Shortcut for `InvalidationSet.use(_ => _.add(input))`. Accepts a single
215
+ * `InvalidationKeyInput` or an array of them.
216
+ */
217
+ add: (input: InvalidationKeyInput | ReadonlyArray<InvalidationKeyInput>) =>
218
+ InvalidationSetRef.use((_) => _.add(input))
219
+ })
220
+ export type InvalidationSet = typeof InvalidationSetRef
221
+
222
+ /** Creates a fresh `InvalidationSet` implementation backed by a `Ref`. */
223
+ export const makeInvalidationSet = (ref: Ref.Ref<ReadonlyArray<InvalidationKey>>): InvalidationSetService => ({
224
+ add: (input) => Ref.update(ref, (keys) => [...keys, ...normalizeInputs(input)]),
225
+ get: Ref.get(ref),
226
+ drain: Ref.getAndSet(ref, [])
227
+ })
228
+
229
+ /**
230
+ * `Rpc.Custom` definition for command RPCs that wrap the success/error schemas
231
+ * with `CommandResponseWithMetaData` / `CommandFailureWithMetaData`. The wrap
232
+ * lets server forward accumulated invalidation keys on both success and
233
+ * handler-thrown failure paths. Middleware-thrown errors bypass the wrap
234
+ * (the handler never ran, so no metadata) and flow raw at the Cause level —
235
+ * the client decodes them via the `rpc.middlewares[*].error` failure-union
236
+ * channel of `Rpc.exitSchema`.
237
+ */
238
+ // eslint-disable-next-line import/namespace
239
+ export interface CommandRpc extends Rpc.Custom {
240
+ readonly out: Rpc.Custom.Out<
241
+ ReturnType<typeof CommandResponseWithMetaData<this["success"] & S.Top>>,
242
+ ReturnType<typeof CommandFailureWithMetaData<this["error"] & S.Top>>
243
+ >
244
+ }
245
+
246
+ /**
247
+ * Custom Rpc constructor for command RPCs.
248
+ * Wraps the success schema with `CommandResponseWithMetaData` and the error
249
+ * schema with `CommandFailureWithMetaData`.
250
+ */
251
+ export const makeCommandRpc = Rpc.custom<CommandRpc>(({ defect, error, success }) => ({
252
+ success: CommandResponseWithMetaData(success),
253
+ error: CommandFailureWithMetaData(error),
254
+ defect
255
+ }))
256
+
257
+ /**
258
+ * `Rpc.Custom` definition for stream RPCs that wrap the success/error schemas
259
+ * with `StreamResponseChunk` / `StreamFailureChunk`.
260
+ */
261
+ // eslint-disable-next-line import/namespace
262
+ export interface StreamRpc extends Rpc.Custom {
263
+ readonly out: Rpc.Custom.Out<
264
+ ReturnType<typeof StreamResponseChunk<this["success"] & S.Top>>,
265
+ ReturnType<typeof StreamFailureChunk<this["error"] & S.Top>>
266
+ >
267
+ }
268
+
269
+ /**
270
+ * Custom Rpc constructor for stream RPCs.
271
+ * Wraps the success schema with `StreamResponseChunk` and
272
+ * the error schema with `StreamFailureChunk`.
273
+ */
274
+ export const makeStreamRpc = Rpc.custom<StreamRpc>(({ defect, error, success }) => ({
275
+ success: StreamResponseChunk(success),
276
+ error: StreamFailureChunk(error),
277
+ defect
278
+ }))