effect-app 3.16.0 → 4.0.0-beta.1

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 (174) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/Array.js +1 -1
  3. package/dist/Chunk.d.ts +2 -4
  4. package/dist/Chunk.d.ts.map +1 -1
  5. package/dist/Chunk.js +2 -2
  6. package/dist/Config/SecretURL.d.ts +2 -12
  7. package/dist/Config/SecretURL.d.ts.map +1 -1
  8. package/dist/Config/SecretURL.js +2 -4
  9. package/dist/Config/internal/configSecretURL.d.ts.map +1 -1
  10. package/dist/Config/internal/configSecretURL.js +3 -4
  11. package/dist/Effect.d.ts +12 -10
  12. package/dist/Effect.d.ts.map +1 -1
  13. package/dist/Effect.js +6 -15
  14. package/dist/Layer.d.ts +15 -9
  15. package/dist/Layer.d.ts.map +1 -1
  16. package/dist/Layer.js +2 -2
  17. package/dist/Operations.d.ts +37 -47
  18. package/dist/Operations.d.ts.map +1 -1
  19. package/dist/Option.js +3 -3
  20. package/dist/Pure.d.ts +17 -6
  21. package/dist/Pure.d.ts.map +1 -1
  22. package/dist/Pure.js +35 -17
  23. package/dist/Schema/Class.d.ts +13 -16
  24. package/dist/Schema/Class.d.ts.map +1 -1
  25. package/dist/Schema/Class.js +5 -27
  26. package/dist/Schema/brand.d.ts +7 -10
  27. package/dist/Schema/brand.d.ts.map +1 -1
  28. package/dist/Schema/brand.js +3 -2
  29. package/dist/Schema/email.d.ts +1 -1
  30. package/dist/Schema/email.d.ts.map +1 -1
  31. package/dist/Schema/email.js +2 -2
  32. package/dist/Schema/ext.d.ts +42 -45
  33. package/dist/Schema/ext.d.ts.map +1 -1
  34. package/dist/Schema/ext.js +49 -63
  35. package/dist/Schema/moreStrings.d.ts +17 -17
  36. package/dist/Schema/moreStrings.d.ts.map +1 -1
  37. package/dist/Schema/moreStrings.js +10 -10
  38. package/dist/Schema/numbers.d.ts +14 -14
  39. package/dist/Schema/numbers.js +5 -5
  40. package/dist/Schema/phoneNumber.d.ts +1 -1
  41. package/dist/Schema/phoneNumber.d.ts.map +1 -1
  42. package/dist/Schema/phoneNumber.js +2 -2
  43. package/dist/Schema/schema.d.ts +2 -3
  44. package/dist/Schema/schema.d.ts.map +1 -1
  45. package/dist/Schema/schema.js +3 -4
  46. package/dist/Schema/strings.d.ts +4 -4
  47. package/dist/Schema/strings.d.ts.map +1 -1
  48. package/dist/Schema/strings.js +4 -4
  49. package/dist/Schema.d.ts +27 -25
  50. package/dist/Schema.d.ts.map +1 -1
  51. package/dist/Schema.js +22 -21
  52. package/dist/ServiceMap.d.ts +44 -0
  53. package/dist/ServiceMap.d.ts.map +1 -0
  54. package/dist/ServiceMap.js +91 -0
  55. package/dist/Set.d.ts +4 -4
  56. package/dist/Set.d.ts.map +1 -1
  57. package/dist/Set.js +14 -14
  58. package/dist/Struct.d.ts +4 -4
  59. package/dist/Struct.d.ts.map +1 -1
  60. package/dist/_ext/Array.d.ts.map +1 -1
  61. package/dist/_ext/Array.js +4 -4
  62. package/dist/_ext/misc.d.ts +2 -2
  63. package/dist/_ext/misc.js +4 -4
  64. package/dist/_ext/ord.ext.js +2 -2
  65. package/dist/builtin.d.ts +0 -8
  66. package/dist/builtin.d.ts.map +1 -1
  67. package/dist/builtin.js +3 -1
  68. package/dist/client/apiClientFactory.d.ts +14 -16
  69. package/dist/client/apiClientFactory.d.ts.map +1 -1
  70. package/dist/client/apiClientFactory.js +38 -23
  71. package/dist/client/clientFor.d.ts +7 -4
  72. package/dist/client/clientFor.d.ts.map +1 -1
  73. package/dist/client/errors.d.ts +36 -48
  74. package/dist/client/errors.d.ts.map +1 -1
  75. package/dist/client/errors.js +19 -9
  76. package/dist/client/makeClient.d.ts +34 -50
  77. package/dist/client/makeClient.d.ts.map +1 -1
  78. package/dist/client/makeClient.js +28 -18
  79. package/dist/http/Request.d.ts +3 -3
  80. package/dist/http/Request.d.ts.map +1 -1
  81. package/dist/http/Request.js +5 -8
  82. package/dist/http/internal/lib.d.ts +12 -13
  83. package/dist/http/internal/lib.d.ts.map +1 -1
  84. package/dist/http/internal/lib.js +14 -14
  85. package/dist/ids.d.ts +9 -9
  86. package/dist/ids.d.ts.map +1 -1
  87. package/dist/ids.js +1 -1
  88. package/dist/index.d.ts +7 -1
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +8 -2
  91. package/dist/logger.d.ts +1 -1
  92. package/dist/middleware.d.ts +2 -2
  93. package/dist/middleware.d.ts.map +1 -1
  94. package/dist/middleware.js +3 -3
  95. package/dist/rpc/MiddlewareMaker.d.ts +17 -16
  96. package/dist/rpc/MiddlewareMaker.d.ts.map +1 -1
  97. package/dist/rpc/MiddlewareMaker.js +27 -18
  98. package/dist/rpc/RpcContextMap.d.ts +4 -4
  99. package/dist/rpc/RpcContextMap.d.ts.map +1 -1
  100. package/dist/rpc/RpcContextMap.js +4 -4
  101. package/dist/rpc/RpcMiddleware.d.ts +24 -40
  102. package/dist/rpc/RpcMiddleware.d.ts.map +1 -1
  103. package/dist/rpc/RpcMiddleware.js +3 -10
  104. package/dist/utils/effectify.js +2 -2
  105. package/dist/utils/gen.d.ts +4 -5
  106. package/dist/utils/gen.d.ts.map +1 -1
  107. package/dist/utils/logLevel.d.ts +1 -1
  108. package/dist/utils/logLevel.d.ts.map +1 -1
  109. package/dist/utils/logLevel.js +6 -7
  110. package/dist/utils/logger.d.ts +4 -3
  111. package/dist/utils/logger.d.ts.map +1 -1
  112. package/dist/utils/logger.js +10 -9
  113. package/dist/utils.d.ts +4 -5
  114. package/dist/utils.d.ts.map +1 -1
  115. package/dist/utils.js +10 -9
  116. package/package.json +12 -21
  117. package/src/Array.ts +1 -1
  118. package/src/Chunk.ts +2 -2
  119. package/src/Config/SecretURL.ts +3 -18
  120. package/src/Config/internal/configSecretURL.ts +2 -3
  121. package/src/Effect.ts +17 -37
  122. package/src/Layer.ts +16 -11
  123. package/src/Option.ts +2 -2
  124. package/src/Pure.ts +60 -26
  125. package/src/Schema/Class.ts +17 -73
  126. package/src/Schema/brand.ts +11 -12
  127. package/src/Schema/email.ts +2 -2
  128. package/src/Schema/ext.ts +114 -167
  129. package/src/Schema/moreStrings.ts +20 -23
  130. package/src/Schema/numbers.ts +4 -4
  131. package/src/Schema/phoneNumber.ts +2 -2
  132. package/src/Schema/schema.ts +2 -3
  133. package/src/Schema/strings.ts +3 -3
  134. package/src/Schema.ts +49 -47
  135. package/src/ServiceMap.ts +187 -0
  136. package/src/Set.ts +19 -19
  137. package/src/Struct.ts +4 -4
  138. package/src/_ext/Array.ts +4 -5
  139. package/src/_ext/misc.ts +4 -4
  140. package/src/_ext/ord.ext.ts +2 -2
  141. package/src/builtin.ts +2 -8
  142. package/src/client/apiClientFactory.ts +74 -59
  143. package/src/client/clientFor.ts +10 -7
  144. package/src/client/errors.ts +28 -22
  145. package/src/client/makeClient.ts +75 -100
  146. package/src/http/Request.ts +5 -8
  147. package/src/http/internal/lib.ts +13 -13
  148. package/src/ids.ts +1 -1
  149. package/src/index.ts +10 -1
  150. package/src/middleware.ts +2 -2
  151. package/src/rpc/MiddlewareMaker.ts +76 -47
  152. package/src/rpc/RpcContextMap.ts +7 -7
  153. package/src/rpc/RpcMiddleware.ts +28 -54
  154. package/src/utils/effectify.ts +1 -1
  155. package/src/utils/gen.ts +8 -6
  156. package/src/utils/logLevel.ts +6 -6
  157. package/src/utils/logger.ts +15 -20
  158. package/src/utils.ts +12 -12
  159. package/test/dist/rpc.test.d.ts.map +1 -1
  160. package/test/schema.test.ts +8 -8
  161. package/test/utils.test.ts +2 -2
  162. package/tsconfig.json +1 -27
  163. package/dist/Context.d.ts +0 -67
  164. package/dist/Context.d.ts.map +0 -1
  165. package/dist/Context.js +0 -207
  166. package/dist/Tag.d.ts +0 -6
  167. package/dist/Tag.d.ts.map +0 -1
  168. package/dist/Tag.js +0 -9
  169. package/dist/Unify.d.ts +0 -27
  170. package/dist/Unify.d.ts.map +0 -1
  171. package/dist/Unify.js +0 -15
  172. package/src/Context.ts +0 -351
  173. package/src/Tag.ts +0 -11
  174. package/src/Unify.ts +0 -40
package/src/Schema.ts CHANGED
@@ -5,10 +5,12 @@ import { fakerArb } from "./faker.js"
5
5
  import { Email as EmailT } from "./Schema/email.js"
6
6
  import { withDefaultMake } from "./Schema/ext.js"
7
7
  import { PhoneNumber as PhoneNumberT } from "./Schema/phoneNumber.js"
8
- import type { A, AST } from "./Schema/schema.js"
8
+ import type { AST } from "./Schema/schema.js"
9
9
  import { extendM } from "./utils.js"
10
10
 
11
11
  export * from "effect/Schema"
12
+ // v4: TaggedError renamed to TaggedErrorClass
13
+ export { TaggedErrorClass as TaggedError } from "effect/Schema"
12
14
 
13
15
  export * from "./Schema/Class.js"
14
16
  export { Class, TaggedClass } from "./Schema/Class.js"
@@ -26,7 +28,8 @@ export * from "./Schema/schema.js"
26
28
  export * from "./Schema/strings.js"
27
29
  export { NonEmptyString } from "./Schema/strings.js"
28
30
 
29
- export * as ParseResult from "effect/ParseResult"
31
+ export * as SchemaIssue from "effect/SchemaIssue"
32
+ export * as SchemaParser from "effect/SchemaParser"
30
33
 
31
34
  export { Void as Void_ } from "effect/Schema"
32
35
 
@@ -39,9 +42,9 @@ export interface WithOptionalSpan {
39
42
 
40
43
  export const Email = EmailT
41
44
  .pipe(
42
- S.annotations({
45
+ S.annotate({
43
46
  // eslint-disable-next-line @typescript-eslint/unbound-method
44
- arbitrary: (): A.LazyArbitrary<Email> => (fc) => fakerArb((faker) => faker.internet.exampleEmail)(fc).map(Email)
47
+ arbitrary: (): any => (fc: any) => fakerArb((faker) => faker.internet.exampleEmail)(fc).map(Email)
45
48
  }),
46
49
  withDefaultMake
47
50
  )
@@ -50,31 +53,23 @@ export type Email = EmailT
50
53
 
51
54
  export const PhoneNumber = PhoneNumberT
52
55
  .pipe(
53
- S.annotations({
54
- arbitrary: (): A.LazyArbitrary<PhoneNumber> => (fc) =>
56
+ S.annotate({
57
+ arbitrary: (): any => (fc: any) =>
55
58
  // eslint-disable-next-line @typescript-eslint/unbound-method
56
59
  fakerArb((faker) => faker.phone.number)(fc).map(PhoneNumber)
57
60
  }),
58
61
  withDefaultMake
59
62
  )
60
63
 
61
- export const makeIs = <A extends { _tag: string }, I, R>(
62
- schema: S.Schema<A, I, R>
64
+ export const makeIs = <A extends { _tag: string }>(
65
+ schema: S.Schema<A>
63
66
  ) => {
64
- const getToBottom = (ast: AST.AST) => {
65
- if (SchemaAST.isTransformation(ast)) {
66
- if (SchemaAST.isDeclaration(ast.to)) {
67
- return getToBottom(ast.from)
68
- }
69
- return getToBottom(ast.to)
70
- }
71
- return ast
72
- }
67
+ // In v4, transformations are stored as encoding on nodes, not as wrapper nodes.
68
+ // Union member ASTs are directly Objects (TypeLiteral equivalent).
73
69
  if (SchemaAST.isUnion(schema.ast)) {
74
- return schema.ast.types.reduce((acc, t) => {
75
- t = getToBottom(t)
76
- if (!SchemaAST.isTypeLiteral(t)) return acc
77
- const tag = Array.findFirst(t.propertySignatures, (_) => {
70
+ return schema.ast.types.reduce((acc: any, t: AST.AST) => {
71
+ if (!SchemaAST.isObjects(t)) return acc
72
+ const tag = Array.findFirst(t.propertySignatures, (_: any) => {
78
73
  if (_.name === "_tag" && SchemaAST.isLiteral(_.type)) {
79
74
  return Option.some(_.type)
80
75
  }
@@ -86,15 +81,16 @@ export const makeIs = <A extends { _tag: string }, I, R>(
86
81
  }
87
82
  return {
88
83
  ...acc,
89
- [String(ast.literal)]: (x: { _tag: string }) => x._tag === ast.literal
84
+ [String((ast as SchemaAST.Literal).literal)]: (x: { _tag: string }) =>
85
+ x._tag === (ast as SchemaAST.Literal).literal
90
86
  }
91
87
  }, {} as Is<A>)
92
88
  }
93
89
  throw new Error("Unsupported")
94
90
  }
95
91
 
96
- export const makeIsAnyOf = <A extends { _tag: string }, I, R>(
97
- schema: S.Schema<A, I, R>
92
+ export const makeIsAnyOf = <A extends { _tag: string }>(
93
+ schema: S.Schema<A>
98
94
  ): IsAny<A> => {
99
95
  if (SchemaAST.isUnion(schema.ast)) {
100
96
  return <Keys extends A["_tag"][]>(...keys: Keys) => (a: A): a is ExtractUnion<A, ElemType<Keys>> =>
@@ -112,52 +108,58 @@ export interface IsAny<A extends { _tag: string }> {
112
108
 
113
109
  export const taggedUnionMap = <
114
110
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
115
- Members extends readonly (S.Schema<{ _tag: string }, any, any> & { fields: { _tag: S.tag<string> } })[]
111
+ Members extends readonly (S.Top & { fields: { _tag: S.tag<string> } })[]
116
112
  >(
117
113
  self: Members
118
114
  ) =>
119
115
  self.reduce((acc, key) => {
120
- // TODO: check upstream what's going on with literals of _tag
121
- const ast = key.fields._tag.ast as S.PropertySignatureDeclaration
122
- const tag = (ast.type as SchemaAST.Literal).literal as string // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
116
+ // TODO: v4 migration PropertySignatureDeclaration removed, need v4 AST traversal
117
+ const ast = key.fields._tag.ast as any
118
+ const tag = ((ast.type ?? ast) as SchemaAST.Literal).literal as string // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
123
119
  ;(acc as any)[tag] = key as any
124
120
  return acc
125
- }, {} as { [Key in Members[number] as ReturnType<Key["fields"]["_tag"][S.TypeId]["_A"]>]: Key })
121
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
122
+ }, {} as any)
126
123
 
127
124
  export const tags = <
128
125
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
129
- Members extends NonEmptyReadonlyArray<(S.Schema<{ _tag: string }, any, any> & { fields: { _tag: S.tag<string> } })>
126
+ Members extends NonEmptyReadonlyArray<(S.Top & { fields: { _tag: S.tag<string> } })>
130
127
  >(
131
128
  self: Members
132
129
  ) =>
133
- S.Literal(...self.map((key) => {
134
- const ast = key.fields._tag.ast as S.PropertySignatureDeclaration
135
- const tag = (ast.type as SchemaAST.Literal).literal
130
+ S.Literals(self.map((key) => {
131
+ // TODO: v4 migration PropertySignatureDeclaration removed, need v4 AST traversal
132
+ const ast = key.fields._tag.ast as any
133
+ const tag = ((ast.type ?? ast) as SchemaAST.Literal).literal
136
134
  return tag
137
135
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
138
- })) as any as S.Literal<
139
- {
140
- [Index in keyof Members]: S.Schema.Type<Members[Index]["fields"]["_tag"]>
141
- }
142
- >
143
- export const ExtendTaggedUnion = <A extends { _tag: string }, I, R>(
144
- schema: S.Schema<A, I, R>
136
+ })) as any
137
+
138
+ export const ExtendTaggedUnion = <A extends { _tag: string }>(
139
+ schema: S.Schema<A>
145
140
  ) =>
146
- extendM(schema, (_) => ({ is: S.is(schema), isA: makeIs(_), isAnyOf: makeIsAnyOf(_) /*, map: taggedUnionMap(a) */ }))
141
+ extendM(
142
+ schema,
143
+ (_) => ({
144
+ is: S.is(schema as any),
145
+ isA: makeIs(_ as any),
146
+ isAnyOf: makeIsAnyOf(_ as any) /*, map: taggedUnionMap(a) */
147
+ })
148
+ )
147
149
 
148
150
  export const TaggedUnion = <
149
151
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
150
- Members extends SchemaAST.Members<S.Schema.Any & { fields: { _tag: S.tag<any> } }>
152
+ Members extends readonly (S.Top & { fields: { _tag: S.tag<any> } })[]
151
153
  >(...a: Members) =>
152
154
  pipe(
153
- S.Union(...a),
155
+ S.Union(a),
154
156
  (_) =>
155
157
  extendM(_, (_) => ({
156
- is: S.is(_),
157
- isA: makeIs(_),
158
- isAnyOf: makeIsAnyOf(_),
158
+ is: S.is(_ as any),
159
+ isA: makeIs(_ as any),
160
+ isAnyOf: makeIsAnyOf(_ as any),
159
161
  tagMap: taggedUnionMap(a),
160
- tags: tags(a)
162
+ tags: tags(a as any)
161
163
  }))
162
164
  )
163
165
 
@@ -0,0 +1,187 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /**
3
+ * We're doing the long way around here with assignTag, TagBase & TagBaseTagged,
4
+ * because there's a typescript compiler issue where it will complain about Equal.symbol, and Hash.symbol not being accessible.
5
+ * https://github.com/microsoft/TypeScript/issues/52644
6
+ */
7
+
8
+ import { type Effect, Layer, type Scope, type Types } from "effect"
9
+ import * as ServiceMap from "effect/ServiceMap"
10
+ import { Yieldable } from "./Effect.js"
11
+
12
+ export * from "effect/ServiceMap"
13
+
14
+ export interface Opaque<Self extends object, in out Shape extends object> extends ServiceMap.Key<Self, Self>, Yieldable<Opaque<Self, Shape>, Self, never, Self> {
15
+ // temp while sorting out https://github.com/Effect-TS/effect-smol/pull/1534
16
+ of(self: Shape): Self
17
+ serviceMap(self: Shape): ServiceMap.ServiceMap<Self>
18
+ // a version that leverages the Shape -> Self conversion
19
+ toLayer: <E, R>(
20
+ eff: Effect.Effect<Shape, E, R>
21
+ ) => Layer.Layer<Self, E, Exclude<R, Scope.Scope>>
22
+ use<A, E, R>(f: (service: Shape) => Effect.Effect<A, E, R>): Effect.Effect<A, E, R | Self>
23
+ useSync<A>(f: (service: Shape) => A): Effect.Effect<A, never, Self>
24
+ }
25
+
26
+ // export interface OpaqueMake<Self extends object, in out Shape extends object, E, R>
27
+ // extends ServiceMap.Service<Self, Self>
28
+ // {
29
+ // // temp while sorting out https://github.com/Effect-TS/effect-smol/pull/1534
30
+ // of(self: Shape): Self
31
+ // serviceMap2(self: Shape): ServiceMap.ServiceMap<Self>
32
+ // // a version that leverages the Shape -> Self conversion
33
+ // toLayer: {
34
+ // <E, R>(
35
+ // eff: Effect.Effect<Shape, E, R>
36
+ // ): Layer.Layer<Self, E, Exclude<R, Scope.Scope>>
37
+ // (): Layer.Layer<Self, E, Exclude<R, Scope.Scope>>
38
+ // }
39
+ // }
40
+
41
+ export function assignTag<Identifier extends object, Shape extends object = Identifier>(
42
+ key: string,
43
+ creationError?: Error
44
+ ) {
45
+ return <S extends object>(cls: S): S & Opaque<Identifier, Shape> => {
46
+ const tag = ServiceMap.Service<Identifier, Shape>(key)
47
+ let fields = tag
48
+ if (Reflect.ownKeys(cls).includes("key")) {
49
+ const { key, ...rest } = tag
50
+ fields = rest as any
51
+ }
52
+ const t = Object.assign(cls, Object.getPrototypeOf(tag), fields)
53
+ if (!creationError) {
54
+ const limit = Error.stackTraceLimit
55
+ Error.stackTraceLimit = 2
56
+ creationError = new Error()
57
+ Error.stackTraceLimit = limit
58
+ }
59
+ // the stack is used to get the location of the tag definition, if a service is not found in the registry
60
+ Object.defineProperty(t, "stack", {
61
+ get() {
62
+ return creationError!.stack
63
+ }
64
+ })
65
+ return t
66
+ }
67
+ }
68
+
69
+ export type ServiceAcessorShape<Self, Type> = Type extends Record<PropertyKey, any> ? {
70
+ [
71
+ k in keyof Type as Type[k] extends ((...args: [...infer Args]) => infer Ret)
72
+ ? ((...args: Readonly<Args>) => Ret) extends Type[k] ? k : never
73
+ : k
74
+ ]: Type[k] extends (...args: [...infer Args]) => Effect.Effect<infer A, infer E, infer R>
75
+ ? (...args: Readonly<Args>) => Effect.Effect<A, E, Self | R>
76
+ : Type[k] extends (...args: [...infer Args]) => infer A
77
+ ? (...args: Readonly<Args>) => Effect.Effect<A, never, Self>
78
+ : Type[k] extends Effect.Effect<infer A, infer E, infer R> ? Effect.Effect<A, E, Self | R>
79
+ : Effect.Effect<Type[k], never, Self>
80
+ }
81
+ : {}
82
+
83
+ /**
84
+ * Only use this in very specific cases where using dependencies directly is prefered, like inside command handlers.
85
+ */
86
+ export const proxify = <T extends object>(Tag: T) =>
87
+ <Self, Shape>():
88
+ & T
89
+ & ServiceAcessorShape<Self, Shape> =>
90
+ {
91
+ const cache = new Map()
92
+ const done = new Proxy(Tag, {
93
+ get(_target: any, prop: any, _receiver) {
94
+ if (prop === "use") {
95
+ // @ts-expect-error abc
96
+ return (body) => (Tag as any).use(body)
97
+ }
98
+ if (prop in Tag) {
99
+ return (Tag as any)[prop]
100
+ }
101
+ if (cache.has(prop)) {
102
+ return cache.get(prop)
103
+ }
104
+ const fn = (...args: Array<any>) => (Tag as any).use((s: any) => s[prop](...args))
105
+ const cn = (Tag as any).use((s: any) => s[prop])
106
+ // @effect-diagnostics effect/floatingEffect:off
107
+ Object.assign(fn, cn)
108
+ Object.setPrototypeOf(fn, Object.getPrototypeOf(cn))
109
+ cache.set(prop, fn)
110
+ return fn
111
+ }
112
+ })
113
+ return done
114
+ }
115
+
116
+ export const TypeId = "~ServiceMap.Opaque"
117
+
118
+ // export function Opaque<const Key extends string>(key: Key) {
119
+ // return <Identifier extends object, Shape extends object>() => {
120
+ // const limit = Error.stackTraceLimit
121
+ // Error.stackTraceLimit = 2
122
+ // const creationError = new Error()
123
+ // Error.stackTraceLimit = limit
124
+ // const c: abstract new(_: never) => Shape & { readonly [TypeId]: Key } = class {} as any
125
+
126
+ // return assignTag<Identifier, Shape>(key, creationError)(c)
127
+ // }
128
+ // }
129
+
130
+ export interface OpaqueClass<Self extends object, in out Identifier extends string, Shape extends object>
131
+ extends Opaque<Self, Shape>
132
+ {
133
+ new(_: never): Shape & { readonly [TypeId]: Identifier }
134
+ readonly key: Identifier
135
+ }
136
+
137
+ // export interface OpaqueClassMake<Self extends object, in out Identifier extends string, Shape extends object, E, R>
138
+ // extends OpaqueMake<Self, Shape, E, R>
139
+ // {
140
+ // new(_: never): Shape & { readonly [TypeId]: Identifier }
141
+ // readonly key: Identifier
142
+ // }
143
+
144
+ export const Opaque: {
145
+ <Self extends object, Shape extends object>(): <
146
+ const Identifier extends string,
147
+ E,
148
+ R = Types.unassigned,
149
+ Args extends ReadonlyArray<any> = never
150
+ >(
151
+ id: Identifier,
152
+ options?: {
153
+ readonly make: ((...args: Args) => Effect.Effect<Shape, E, R>) | Effect.Effect<Shape, E, R> | undefined
154
+ } | undefined
155
+ ) =>
156
+ & OpaqueClass<Self, Identifier, Shape>
157
+ & ([Types.unassigned] extends [R] ? unknown
158
+ : {
159
+ readonly make: [Args] extends [never] ? Effect.Effect<Shape, E, R>
160
+ : (...args: Args) => Effect.Effect<Shape, E, R>
161
+ })
162
+ <Self extends object>(): <
163
+ const Identifier extends string,
164
+ Make extends Effect.Effect<any, any, any> | ((...args: any) => Effect.Effect<any, any, any>)
165
+ >(
166
+ id: Identifier,
167
+ options: {
168
+ readonly make: Make
169
+ }
170
+ ) =>
171
+ & OpaqueClass<
172
+ Self,
173
+ Identifier,
174
+ Make extends
175
+ | Effect.Effect<infer _A, infer _E, infer _R>
176
+ | ((...args: infer _Args) => Effect.Effect<infer _A, infer _E, infer _R>) ? _A
177
+ : never
178
+ >
179
+ & { readonly make: Make }
180
+ } = () => (id: string, options: any) => {
181
+ const svc = ServiceMap.Service()(id, options) as any
182
+ return Object.assign(svc, {
183
+ toLayer: (eff: Effect.Effect<any, any, any>) => {
184
+ return Layer.effect(svc as any, eff)
185
+ }
186
+ })
187
+ }
package/src/Set.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // ets_tracing: off
2
2
 
3
- import { Array, type Either, type Equivalence, Option, type Order } from "effect"
3
+ import { Array, type Equivalence, Option, type Order, type Result } from "effect"
4
4
  import { not } from "effect/Predicate"
5
5
  import { identity, pipe, type Predicate, type Refinement, tuple } from "./Function.js"
6
6
 
@@ -19,7 +19,7 @@ export function findFirst_<A, B extends A>(
19
19
  ): Option.Option<B>
20
20
  export function findFirst_<A>(set: ReadonlySet<A>, predicate: Predicate<A>): Option.Option<A>
21
21
  export function findFirst_<A>(set: ReadonlySet<A>, predicate: Predicate<A>): Option.Option<A> {
22
- return Option.fromNullable([...set].find(predicate))
22
+ return Option.fromNullishOr([...set].find(predicate))
23
23
  }
24
24
 
25
25
  export function findFirstMap_<A, B>(
@@ -337,9 +337,9 @@ export function elem<A>(E: Equivalence.Equivalence<A>): (a: A) => (set: Set<A>)
337
337
  export function partitionMap<B, C>(
338
338
  EB: Equivalence.Equivalence<B>,
339
339
  EC: Equivalence.Equivalence<C>
340
- ): <A>(f: (a: A) => Either.Either<C, B>) => (set: Set<A>) => readonly [Set<B>, Set<C>] {
340
+ ): <A>(f: (a: A) => Result.Result<C, B>) => (set: Set<A>) => readonly [Set<B>, Set<C>] {
341
341
  const pm = partitionMap_(EB, EC)
342
- return <A>(f: (a: A) => Either.Either<C, B>) => (set: Set<A>) => pm(set, f)
342
+ return <A>(f: (a: A) => Result.Result<C, B>) => (set: Set<A>) => pm(set, f)
343
343
  }
344
344
 
345
345
  /**
@@ -348,8 +348,8 @@ export function partitionMap<B, C>(
348
348
  export function partitionMap_<B, C>(
349
349
  EB: Equivalence.Equivalence<B>,
350
350
  EC: Equivalence.Equivalence<C>
351
- ): <A>(set: Set<A>, f: (a: A) => Either.Either<C, B>) => readonly [Set<B>, Set<C>] {
352
- return <A>(set: Set<A>, f: (a: A) => Either.Either<C, B>) => {
351
+ ): <A>(set: Set<A>, f: (a: A) => Result.Result<C, B>) => readonly [Set<B>, Set<C>] {
352
+ return <A>(set: Set<A>, f: (a: A) => Result.Result<C, B>) => {
353
353
  const values = set.values()
354
354
  let e: Next<A>
355
355
  const left = new Set<B>()
@@ -359,14 +359,14 @@ export function partitionMap_<B, C>(
359
359
  while (!(e = values.next() as any).done) {
360
360
  const v = f(e.value)
361
361
  switch (v._tag) {
362
- case "Left":
363
- if (!hasB(left, v.left)) {
364
- left.add(v.left)
362
+ case "Failure":
363
+ if (!hasB(left, v.failure)) {
364
+ left.add(v.failure)
365
365
  }
366
366
  break
367
- case "Right":
368
- if (!hasC(right, v.right)) {
369
- right.add(v.right)
367
+ case "Success":
368
+ if (!hasC(right, v.success)) {
369
+ right.add(v.success)
370
370
  }
371
371
  break
372
372
  }
@@ -528,7 +528,7 @@ export function compact<A>(E: Equivalence.Equivalence<A>): (fa: Set<Option.Optio
528
528
  export function separate<E, A>(
529
529
  EE: Equivalence.Equivalence<E>,
530
530
  EA: Equivalence.Equivalence<A>
531
- ): (fa: Set<Either.Either<A, E>>) => readonly [Set<E>, Set<A>] {
531
+ ): (fa: Set<Result.Result<A, E>>) => readonly [Set<E>, Set<A>] {
532
532
  return (fa) => {
533
533
  const elemEE = elem_(EE)
534
534
  const elemEA = elem_(EA)
@@ -536,14 +536,14 @@ export function separate<E, A>(
536
536
  const right: MutableSet<A> = new Set()
537
537
  fa.forEach((e) => {
538
538
  switch (e._tag) {
539
- case "Left":
540
- if (!elemEE(left, e.left)) {
541
- left.add(e.left)
539
+ case "Failure":
540
+ if (!elemEE(left, e.failure)) {
541
+ left.add(e.failure)
542
542
  }
543
543
  break
544
- case "Right":
545
- if (!elemEA(right, e.right)) {
546
- right.add(e.right)
544
+ case "Success":
545
+ if (!elemEA(right, e.success)) {
546
+ right.add(e.success)
547
547
  }
548
548
  break
549
549
  }
package/src/Struct.ts CHANGED
@@ -18,13 +18,13 @@ export * from "effect/Struct"
18
18
  */
19
19
  export const pick: {
20
20
  <Keys extends Array<PropertyKey>>(
21
- ...keys: Keys
21
+ keys: Keys
22
22
  ): <S extends { [K in Keys[number]]?: any }>(
23
23
  s: S
24
24
  ) => Types.MatchRecord<S, { [K in Keys[number]]?: S[K] }, Pick<S, Keys[number]>>
25
25
  <S extends object, Keys extends Array<keyof S>>(
26
26
  s: S,
27
- ...keys: Keys
27
+ keys: Keys
28
28
  ): Types.MatchRecord<S, { [K in Keys[number]]?: S[K] }, Pick<S, Keys[number]>>
29
29
  } = Struct.pick
30
30
 
@@ -45,10 +45,10 @@ export type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K
45
45
  */
46
46
  export const omit: {
47
47
  <Keys extends Array<PropertyKey>>(
48
- ...keys: Keys
48
+ keys: Keys
49
49
  ): <S extends { [K in Keys[number]]?: any }>(s: S) => DistributiveOmit<S, Keys[number]>
50
50
  <S extends object, Keys extends Array<keyof S>>(
51
51
  s: S,
52
- ...keys: Keys
52
+ keys: Keys
53
53
  ): DistributiveOmit<S, Keys[number]>
54
54
  } = Struct.omit as any
package/src/_ext/Array.ts CHANGED
@@ -7,12 +7,11 @@ function getFirstBy<A, Type extends string>(
7
7
  id: A[typeof idKey],
8
8
  type: Type
9
9
  ) {
10
- return Chunk
11
- .fromIterable(a)
12
- .pipe(
13
- Chunk.findFirst((_) => Equal.equals(_[idKey], id)),
14
- Effect.mapError(() => new NotFoundError<Type>({ type, id }))
10
+ return Effect
11
+ .fromOption(
12
+ Chunk.fromIterable(a).pipe(Chunk.findFirst((_) => Equal.equals(_[idKey], id)))
15
13
  )
14
+ .pipe(Effect.mapError(() => new NotFoundError<Type>({ type, id })))
16
15
  }
17
16
 
18
17
  export function makeGetFirstBy<A>() {
package/src/_ext/misc.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Effect, Either, Option, type Scope } from "effect"
1
+ import { Effect, Option, Result, type Scope } from "effect"
2
2
  import type { LazyArg } from "effect-app/Function"
3
3
 
4
4
  export type _R<T extends Effect.Effect<any, any, any>> = [T] extends [
@@ -21,8 +21,8 @@ export function encaseMaybeInEffect_<E, A>(
21
21
  export function encaseMaybeEither_<E, A>(
22
22
  o: Option.Option<A>,
23
23
  onError: LazyArg<E>
24
- ): Either.Either<A, E> {
25
- return Option.match(o, { onNone: () => Either.left(onError()), onSome: Either.right })
24
+ ): Result.Result<A, E> {
25
+ return Option.match(o, { onNone: () => Result.fail(onError()), onSome: Result.succeed })
26
26
  }
27
27
 
28
28
  export function toNullable<R, E, A>(
@@ -35,7 +35,7 @@ export function scope<R, E, A, R2, E2, A2>(
35
35
  scopedEffect: Effect.Effect<A, E, R | Scope.Scope>,
36
36
  effect: Effect.Effect<A2, E2, R2>
37
37
  ): Effect.Effect<A2, E | E2, Exclude<R | R2, Scope.Scope>> {
38
- return Effect.zipRight(scopedEffect, effect).pipe(Effect.scoped)
38
+ return Effect.andThen(scopedEffect, effect).pipe(Effect.scoped)
39
39
  }
40
40
 
41
41
  export function flatMapScoped<R, E, A, R2, E2, A2>(
@@ -13,7 +13,7 @@ export function uniq<A>(E: Equivalence.Equivalence<A>) {
13
13
  return (self: Chunk.Chunk<A>): Chunk.Chunk<A> => {
14
14
  let out = Chunk.fromIterable<A>([])
15
15
  for (let i = 0; i < self.length; i++) {
16
- const a = Chunk.unsafeGet(self, i)
16
+ const a = Chunk.getUnsafe(self, i)
17
17
  if (!elem(E, a)(out)) {
18
18
  out = Chunk.append(out, a)
19
19
  }
@@ -30,7 +30,7 @@ export function uniq<A>(E: Equivalence.Equivalence<A>) {
30
30
  export function elem<A>(E: Equivalence.Equivalence<A>, value: A) {
31
31
  return (self: Chunk.Chunk<A>): boolean => {
32
32
  for (let i = 0; i < self.length; i++) {
33
- if (E(Chunk.unsafeGet(self, i), value)) {
33
+ if (E(Chunk.getUnsafe(self, i), value)) {
34
34
  return true
35
35
  }
36
36
  }
package/src/builtin.ts CHANGED
@@ -54,11 +54,5 @@ declare module "effect/Option" {
54
54
  }
55
55
  }
56
56
 
57
- declare module "effect/Either" {
58
- export interface Left<E, A> {
59
- get right(): A | undefined
60
- }
61
- export interface Right<E, A> {
62
- get left(): E | undefined
63
- }
64
- }
57
+ // TODO: v4 migration — Either module augmentation removed (Either → Result)
58
+ // Previously added .right to Left and .left to Right for convenience access