@planet-matrix/mobius-model 0.9.0 → 0.10.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 (63) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/oxlint.config.ts +1 -2
  3. package/package.json +5 -5
  4. package/scripts/build.ts +2 -52
  5. package/src/basic/promise.ts +141 -71
  6. package/src/drizzle/pagination.ts +0 -2
  7. package/src/event/class-event-proxy.ts +0 -2
  8. package/src/event/instance-event-proxy.ts +0 -2
  9. package/src/exception/README.md +28 -19
  10. package/src/exception/error/error.ts +123 -0
  11. package/src/exception/error/index.ts +2 -0
  12. package/src/exception/error/match.ts +38 -0
  13. package/src/exception/error/must-fix.ts +17 -0
  14. package/src/exception/index.ts +2 -0
  15. package/src/file-system/find.ts +53 -0
  16. package/src/file-system/index.ts +2 -0
  17. package/src/file-system/path.ts +76 -0
  18. package/src/file-system/resolve.ts +22 -0
  19. package/src/form/inputor-controller/base.ts +0 -13
  20. package/src/form/inputor-controller/form.ts +0 -2
  21. package/src/http/api/api-type.ts +0 -3
  22. package/src/http/api-adapter/api-result-arktype.ts +0 -3
  23. package/src/index.ts +2 -0
  24. package/src/openai/openai.ts +0 -1
  25. package/src/request/fetch/browser.ts +0 -5
  26. package/src/request/fetch/nodejs.ts +0 -5
  27. package/src/request/request/base.ts +0 -4
  28. package/src/request/request/general.ts +0 -1
  29. package/src/result/controller.ts +11 -7
  30. package/src/result/either.ts +230 -60
  31. package/src/result/generator.ts +168 -0
  32. package/src/result/index.ts +1 -0
  33. package/src/route/router/router.ts +0 -1
  34. package/src/route/uri/hash.ts +0 -1
  35. package/src/route/uri/search.ts +0 -1
  36. package/src/service/README.md +1 -0
  37. package/src/service/index.ts +1 -0
  38. package/src/service/service.ts +110 -0
  39. package/src/socket/client/socket-unit.ts +0 -2
  40. package/src/socket/server/socket-unit.ts +0 -1
  41. package/src/tube/helper.ts +0 -1
  42. package/src/weixin/official-account/authorization.ts +0 -2
  43. package/src/weixin/official-account/js-api.ts +0 -2
  44. package/src/weixin/open/oauth2.ts +0 -2
  45. package/tests/unit/aio/json.spec.ts +0 -1
  46. package/tests/unit/basic/promise.spec.ts +158 -50
  47. package/tests/unit/credential/api-key.spec.ts +0 -1
  48. package/tests/unit/credential/password.spec.ts +0 -1
  49. package/tests/unit/exception/error/error.spec.ts +83 -0
  50. package/tests/unit/exception/error/match.spec.ts +81 -0
  51. package/tests/unit/http/api-adapter/node-http.spec.ts +0 -4
  52. package/tests/unit/identifier/uuid.spec.ts +0 -1
  53. package/tests/unit/request/request/base.spec.ts +0 -3
  54. package/tests/unit/request/request/general.spec.ts +0 -1
  55. package/tests/unit/result/controller.spec.ts +82 -0
  56. package/tests/unit/result/either.spec.ts +377 -0
  57. package/tests/unit/result/generator.spec.ts +273 -0
  58. package/tests/unit/route/router/route.spec.ts +0 -1
  59. package/tests/unit/route/uri/pathname.spec.ts +0 -1
  60. package/tests/unit/socket/server.spec.ts +0 -2
  61. package/vite.config.ts +2 -1
  62. package/dist/index.js +0 -720
  63. package/dist/index.js.map +0 -1005
@@ -229,7 +229,6 @@ export class NodejsFetch<
229
229
  */
230
230
  async getJson(): Promise<FetchOutputJsonData<Output>> {
231
231
  const response = await this.getResponse()
232
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
233
232
  return await response.json() as FetchOutputJsonData<Output>
234
233
  }
235
234
 
@@ -238,7 +237,6 @@ export class NodejsFetch<
238
237
  */
239
238
  async getText(): Promise<FetchOutputTextData<Output>> {
240
239
  const response = await this.getResponse()
241
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
242
240
  return await response.text() as FetchOutputTextData<Output>
243
241
  }
244
242
 
@@ -247,7 +245,6 @@ export class NodejsFetch<
247
245
  */
248
246
  async getBlob(): Promise<FetchOutputBlobData<Output>> {
249
247
  const response = await this.getResponse()
250
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
251
248
  return await response.blob() as FetchOutputBlobData<Output>
252
249
  }
253
250
 
@@ -256,7 +253,6 @@ export class NodejsFetch<
256
253
  */
257
254
  async getArrayBuffer(): Promise<FetchOutputArrayBufferData<Output>> {
258
255
  const response = await this.getResponse()
259
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
260
256
  return await response.arrayBuffer() as FetchOutputArrayBufferData<Output>
261
257
  }
262
258
 
@@ -270,7 +266,6 @@ export class NodejsFetch<
270
266
  throw new Error("Response body stream is unavailable.")
271
267
  }
272
268
 
273
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
274
269
  return response.body as FetchOutputStreamData<Output>
275
270
  }
276
271
  }
@@ -131,7 +131,6 @@ export abstract class BaseRequest<R extends Resource = Resource> {
131
131
  * 从成功输出中提取成功数据。
132
132
  */
133
133
  protected extractSuccessData(response: ResourceSuccessOutput<R>): ResourceSuccessData<R> {
134
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
135
134
  return response['data'] as ResourceSuccessData<R>
136
135
  }
137
136
 
@@ -146,7 +145,6 @@ export abstract class BaseRequest<R extends Resource = Resource> {
146
145
  * 从错误输出中提取错误数据。
147
146
  */
148
147
  protected extractErrorData(response: ResourceErrorOutput<R>): ResourceErrorData<R> {
149
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
150
148
  return response['data'] as ResourceErrorData<R>
151
149
  }
152
150
 
@@ -159,7 +157,6 @@ export abstract class BaseRequest<R extends Resource = Resource> {
159
157
  const { fetchFactory, modifyRequestOptions } = this.options
160
158
 
161
159
  const preparedOptions = modifyRequestOptions !== undefined
162
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
163
160
  ? modifyRequestOptions(options as RequestOptions<R["path"], R>)
164
161
  : options
165
162
 
@@ -184,7 +181,6 @@ export abstract class BaseRequest<R extends Resource = Resource> {
184
181
  data: ResourceOutput<Extract<R, { path: Path }>>
185
182
  }
186
183
  }[typeof responseType]
187
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
188
184
  const preparedFetch = (fetchFactory ?? generalFetch)(preparedOptions) as BaseFetch<FetchInput, FetchOutput>
189
185
 
190
186
  if (responseType === "json") {
@@ -50,7 +50,6 @@ export class GeneralRequest<R extends GeneralResource = GeneralResource>
50
50
  extends BaseRequest<GeneralResourceToResource<R>> {
51
51
  constructor(options: GeneralRequestOptions<R>) {
52
52
  const generatePatchOutput = (context: GeneratePatchOutputContext): ResourcePatchOutput<GeneralResourceToResource<R>> => {
53
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
54
53
  return {
55
54
  status: "unknown",
56
55
  data: context
@@ -10,15 +10,19 @@ export class Controller<L, R> {
10
10
  return Right.isRight(target)
11
11
  }
12
12
 
13
- private promise: Promise<Either<L, R>>
14
- private resolve: (value: Either<L, R>) => void
13
+ protected promise: Promise<Either<L, R>>
14
+ protected resolve: (value: Either<L, R>) => void
15
+ protected reject: (value: L) => void
15
16
 
16
17
  constructor() {
17
18
  let _resolve: (value: Either<L, R>) => void
18
- this.promise = new Promise((resolve) => {
19
+ let _reject: (value: L) => void
20
+ this.promise = new Promise((resolve, reject) => {
19
21
  _resolve = resolve
22
+ _reject = reject
20
23
  })
21
24
  this.resolve = _resolve!
25
+ this.reject = _reject!
22
26
  }
23
27
 
24
28
  get value(): Promise<Either<L, R>> {
@@ -46,9 +50,9 @@ export class Controller<L, R> {
46
50
  }
47
51
  }
48
52
 
49
- type ExtractLeft<E> = E extends Either<infer L, infer _> ? L : never
50
- type ExtractRight<E> = E extends Either<infer _, infer R> ? R : never
53
+ type GetLeft<E> = E extends Either<infer L, infer _> ? L : never
54
+ type GetRight<E> = E extends Either<infer _, infer R> ? R : never
51
55
  export const controllerFromEitherType = <E extends Either<unknown, unknown>>(
52
- ): Controller<ExtractLeft<E>, ExtractRight<E>> => {
53
- return new Controller<ExtractLeft<E>, ExtractRight<E>>()
56
+ ): Controller<GetLeft<E>, GetRight<E>> => {
57
+ return new Controller<GetLeft<E>, GetRight<E>>()
54
58
  }
@@ -1,24 +1,26 @@
1
1
 
2
2
  // oxlint-disable-next-line typescript/no-explicit-any
3
- type AnyEither = Either<any, any>
4
- type GetRight<Eithers> = Eithers extends []
3
+ export type AnyEither = Either<any, any>
4
+ export type GetLeft<T> = T extends Either<infer Left, unknown> ? Left : never
5
+ export type GetRight<T> = T extends Either<unknown, infer Right> ? Right : never
6
+ export type GetRights<Eithers> = Eithers extends []
5
7
  ? []
6
8
  : (
7
- Eithers extends [infer AssumeEither, ...infer xs]
9
+ Eithers extends [infer Item, ...infer xs]
8
10
  ? (
9
- AssumeEither extends Either<unknown, infer Right>
10
- ? [Right, ...GetRight<xs>]
11
+ Item extends Either<unknown, infer Right>
12
+ ? [Right, ...GetRights<xs>]
11
13
  : never
12
14
  )
13
15
  : never
14
16
  )
15
- type GetLeft<Eithers> = Eithers extends []
17
+ export type GetLefts<Eithers> = Eithers extends []
16
18
  ? []
17
19
  : (
18
- Eithers extends [infer AssumeEither, ...infer xs]
20
+ Eithers extends [infer Item, ...infer xs]
19
21
  ? (
20
- AssumeEither extends Either<infer Left, unknown>
21
- ? [Left, ...GetLeft<xs>]
22
+ Item extends Either<infer Left, unknown>
23
+ ? [Left, ...GetLefts<xs>]
22
24
  : never
23
25
  )
24
26
  : never
@@ -26,72 +28,115 @@ type GetLeft<Eithers> = Eithers extends []
26
28
  type TupleToUnion<Tuple> = Tuple extends unknown[] ? Tuple[number] : never
27
29
 
28
30
  export abstract class Either<L, R> {
31
+ static isEither<L, R>(target: unknown): target is Either<L, R> {
32
+ return target instanceof Either
33
+ }
34
+
35
+ static isLeft<L, R>(target: unknown): target is Left<L, R> {
36
+ return Left.isLeft(target)
37
+ }
38
+
39
+ static isRight<L, R>(target: unknown): target is Right<L, R> {
40
+ return Right.isRight(target)
41
+ }
42
+
43
+ static left<L>(value: L): Either<L, never>
44
+ static left<L, R>(value: L): Either<L, R>
29
45
  static left<L, R>(value: L): Either<L, R> {
30
46
  return new Left(value)
31
47
  }
32
48
 
49
+ static right<R>(value: R): Either<never, R>
50
+ static right<L, R>(value: R): Either<L, R>
33
51
  static right<L, R>(value: R): Either<L, R> {
34
52
  return new Right(value)
35
53
  }
36
54
 
55
+ static pure<R>(value: R): Either<never, R>
56
+ static pure<L, R>(value: R): Either<L, R>
37
57
  static pure<L, R>(value: R): Either<L, R> {
38
58
  return new Right(value)
39
59
  }
40
60
 
41
61
  static lift<NewR, Eithers extends AnyEither[]>(
42
62
  eithers: [...Eithers],
43
- map: (eitherRights: GetRight<Eithers>) => NewR,
44
- ): Either<TupleToUnion<GetLeft<Eithers>>, NewR> {
63
+ map: (eitherRights: GetRights<Eithers>) => NewR,
64
+ ): Either<TupleToUnion<GetLefts<Eithers>>, NewR> {
45
65
  const firstLeft = eithers.find(either => either.isLeft())
46
66
  if (firstLeft !== undefined) {
47
- return firstLeft as Either<TupleToUnion<GetLeft<Eithers>>, NewR>
67
+ return firstLeft as Either<TupleToUnion<GetLefts<Eithers>>, NewR>
48
68
  }
49
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
50
69
  const rights = eithers.map(either => {
51
70
  // oxlint-disable-next-line typescript/no-unsafe-return
52
71
  return either.assertRight().getRight()
53
- }) as GetRight<Eithers>
72
+ }) as GetRights<Eithers>
54
73
  const newRightValue = map(rights)
55
74
  return Either.pure(newRightValue)
56
75
  }
57
76
 
58
- abstract map<NewR>(map: (value: R) => NewR): Either<L, NewR>
59
- abstract mapLeft<NewL>(map: (value: L) => NewL): Either<NewL, R>
60
- abstract bind<NewR>(bind: (value: R) => Either<L, NewR>): Either<L, NewR>
77
+ abstract getValue(): L | R
78
+
79
+ abstract getLeft(): L
80
+ abstract getRight(): R
81
+ abstract getRightOr(or: R): R
61
82
 
62
83
  abstract isLeft(): this is Left<L, R>
63
84
  abstract isRight(): this is Right<L, R>
64
- abstract getValue(): L | R
65
85
 
66
86
  abstract assertLeft(): Left<L, R>
67
87
  abstract assertRight(): Right<L, R>
68
88
 
69
- abstract match<X>(onLeft: (value: L) => X, onRight: (value: R) => X): X
89
+ abstract tap(effects: {
90
+ left?: ((value: L) => void) | undefined
91
+ right?: ((value: R) => void) | undefined
92
+ }): Either<L, R>
93
+ abstract tapLeft(effect: (value: L) => void): Either<L, R>
94
+ abstract tapRight(effect: (value: R) => void): Either<L, R>
95
+
96
+ abstract mapLeft<NewL>(map: (value: L) => NewL): Either<NewL, R>
97
+ abstract mapRight<NewR>(map: (value: R) => NewR): Either<L, NewR>
98
+ abstract bind<NewL, NewR>(bind: (value: R) => Either<NewL, NewR>): Either<L | NewL, NewR>
99
+ abstract bindAsync<NewL, NewR>(bind: (value: R) => Promise<Either<NewL, NewR>>): Promise<Either<L | NewL, NewR>>
100
+
101
+ abstract match<X>(
102
+ left: (value: L) => X,
103
+ right: (value: R) => X
104
+ ): X
105
+ abstract matchAsync<X>(
106
+ left: (value: L) => Promise<X>,
107
+ right: (value: R) => Promise<X>
108
+ ): Promise<X>
70
109
 
71
110
  abstract mplus(either: Either<L, R>): Either<L, R>
111
+
112
+ abstract [Symbol.iterator](): Generator<Either<L, R>, R, R>
113
+ // Async consumers can fall back to Symbol.iterator, but we still expose the
114
+ // same semantics explicitly so Either remains self-descriptive as an async iterable.
115
+ abstract [Symbol.asyncIterator](): AsyncGenerator<Either<L, R>, R, unknown>
72
116
  }
73
- export class Left<L, R> extends Either<L, R> {
74
- static isLeft<L, R>(target: unknown): target is Left<L, R> {
75
- return target instanceof Left
76
- }
77
117
 
78
- private value: L
118
+ export class Left<L, R> extends Either<L, R> {
119
+ protected value: L
79
120
 
80
121
  constructor(value: L) {
81
122
  super()
82
123
  this.value = value
83
124
  }
84
125
 
85
- map<NewR>(_map: (value: R) => NewR): Either<L, NewR> {
86
- return new Left(this.value)
126
+ getValue(): L | R {
127
+ return this.value
87
128
  }
88
129
 
89
- mapLeft<NewL>(map: (value: L) => NewL): Either<NewL, R> {
90
- return new Left(map(this.value))
130
+ getLeft(): L {
131
+ return this.value
91
132
  }
92
133
 
93
- bind<NewR>(_map: (value: R) => Either<L, NewR>): Either<L, NewR> {
94
- return new Left(this.value)
134
+ getRight(): R {
135
+ throw new Error("Cannot get right value from Left")
136
+ }
137
+
138
+ getRightOr(or: R): R {
139
+ return or
95
140
  }
96
141
 
97
142
  isLeft(): this is Left<L, R> {
@@ -102,53 +147,103 @@ export class Left<L, R> extends Either<L, R> {
102
147
  return false
103
148
  }
104
149
 
105
- getLeft(): L {
106
- return this.value
150
+ assertLeft(): this {
151
+ return this
107
152
  }
108
153
 
109
- getValue(): L | R {
110
- return this.value
154
+ assertRight(): Right<L, R> {
155
+ throw new Error("Assert failed")
111
156
  }
112
157
 
113
- assertLeft(): this {
158
+ tap(effects: {
159
+ left?: ((value: L) => void) | undefined
160
+ right?: ((value: R) => void) | undefined
161
+ }): Either<L, R> {
162
+ if (effects.left !== undefined) {
163
+ effects.left(this.value)
164
+ }
114
165
  return this
115
166
  }
116
167
 
117
- assertRight(): Right<L, R> {
118
- throw new Error("Assert failed")
168
+ tapLeft(effect: (value: L) => void): Either<L, R> {
169
+ effect(this.value)
170
+ return this
171
+ }
172
+
173
+ tapRight(_effect: (value: R) => void): Either<L, R> {
174
+ return this
119
175
  }
120
176
 
121
- match<X>(onLeft: (value: L) => X, _onRight: (value: R) => X): X {
122
- return onLeft(this.value)
177
+ mapLeft<NewL>(map: (value: L) => NewL): Either<NewL, R> {
178
+ return new Left(map(this.value))
179
+ }
180
+
181
+ mapRight<NewR>(_map: (value: R) => NewR): Either<L, NewR> {
182
+ return new Left(this.value)
183
+ }
184
+
185
+ bind<NewL, NewR>(_map: (value: R) => Either<NewL, NewR>): Either<L | NewL, NewR> {
186
+ return new Left(this.value) as Either<L | NewL, NewR>
187
+ }
188
+
189
+ async bindAsync<NewL, NewR>(_bind: (value: R) => Promise<Either<NewL, NewR>>): Promise<Either<L | NewL, NewR>> {
190
+ return await Promise.resolve(new Left(this.value) as Either<L | NewL, NewR>)
191
+ }
192
+
193
+ match<X>(
194
+ left: (value: L) => X,
195
+ _right: (value: R) => X
196
+ ): X {
197
+ return left(this.value)
198
+ }
199
+
200
+ async matchAsync<X>(
201
+ left: (value: L) => Promise<X>,
202
+ _right: (value: R) => Promise<X>
203
+ ): Promise<X> {
204
+ return await left(this.value)
123
205
  }
124
206
 
125
207
  mplus(either: Either<L, R>): Either<L, R> {
126
208
  return either
127
209
  }
128
- }
129
210
 
130
- export class Right<L, R> extends Either<L, R> {
131
- static isRight<L, R>(target: unknown): target is Right<L, R> {
132
- return target instanceof Right
211
+ *[Symbol.iterator](): Generator<Either<L, R>, R, R> {
212
+ yield this
213
+ throw new Error("Cannot extract right value from Left")
214
+ }
215
+
216
+ // This mirrors the sync iterator exactly; it is explicit protocol support,
217
+ // not a requirement for async yield* fallback.
218
+ async *[Symbol.asyncIterator](): AsyncGenerator<Either<L, R>, R, unknown> {
219
+ await Promise.resolve()
220
+ yield this
221
+ throw new Error("Cannot extract right value from Left")
133
222
  }
223
+ }
134
224
 
135
- private value: R
225
+ export class Right<L, R> extends Either<L, R> {
226
+ protected value: R
136
227
 
137
228
  constructor(value: R) {
138
229
  super()
139
230
  this.value = value
140
231
  }
141
232
 
142
- map<NewR>(map: (value: R) => NewR): Either<L, NewR> {
143
- return new Right(map(this.value))
233
+ getValue(): L | R {
234
+ return this.value
144
235
  }
145
236
 
146
- mapLeft<NewL>(_map: (value: L) => NewL): Either<NewL, R> {
147
- return new Right(this.value)
237
+ getLeft(): L {
238
+ throw new Error("Cannot get left value from Right")
239
+ }
240
+
241
+ getRight(): R {
242
+ return this.value
148
243
  }
149
244
 
150
- bind<NewR>(map: (value: R) => Either<L, NewR>): Either<L, NewR> {
151
- return map(this.value)
245
+ getRightOr(_or: R): R {
246
+ return this.value
152
247
  }
153
248
 
154
249
  isLeft(): this is Left<L, R> {
@@ -159,35 +254,110 @@ export class Right<L, R> extends Either<L, R> {
159
254
  return true
160
255
  }
161
256
 
162
- getRight(): R {
163
- return this.value
257
+ assertLeft(): Left<L, R> {
258
+ throw new Error("Assert failed")
164
259
  }
165
260
 
166
- getValue(): L | R {
167
- return this.value
261
+ assertRight(): this {
262
+ return this
168
263
  }
169
264
 
170
- assertLeft(): Left<L, R> {
171
- throw new Error("Assert failed")
265
+ tap(effects: {
266
+ left?: ((value: L) => void) | undefined
267
+ right?: ((value: R) => void) | undefined
268
+ }): Either<L, R> {
269
+ if (effects.right !== undefined) {
270
+ effects.right(this.value)
271
+ }
272
+ return this
172
273
  }
173
274
 
174
- assertRight(): this {
275
+ tapLeft(_effect: (value: L) => void): Either<L, R> {
175
276
  return this
176
277
  }
177
278
 
178
- match<X>(_onLeft: (value: L) => X, onRight: (value: R) => X): X {
179
- return onRight(this.value)
279
+ tapRight(effect: (value: R) => void): Either<L, R> {
280
+ effect(this.value)
281
+ return this
282
+ }
283
+
284
+ mapLeft<NewL>(_map: (value: L) => NewL): Either<NewL, R> {
285
+ return new Right(this.value)
286
+ }
287
+
288
+ mapRight<NewR>(map: (value: R) => NewR): Either<L, NewR> {
289
+ return new Right(map(this.value))
290
+ }
291
+
292
+ bind<NewL, NewR>(map: (value: R) => Either<NewL, NewR>): Either<L | NewL, NewR> {
293
+ return map(this.value) as Either<L | NewL, NewR>
294
+ }
295
+
296
+ async bindAsync<NewL, NewR>(bind: (value: R) => Promise<Either<NewL, NewR>>): Promise<Either<L | NewL, NewR>> {
297
+ return await bind(this.value) as Either<L | NewL, NewR>
298
+ }
299
+
300
+ match<X>(
301
+ _left: (value: L) => X,
302
+ right: (value: R) => X
303
+ ): X {
304
+ return right(this.value)
305
+ }
306
+
307
+ async matchAsync<X>(
308
+ _left: (value: L) => Promise<X>,
309
+ right: (value: R) => Promise<X>
310
+ ): Promise<X> {
311
+ return await right(this.value)
180
312
  }
181
313
 
182
314
  mplus(_either: Either<L, R>): Either<L, R> {
183
315
  return this
184
316
  }
317
+
318
+ *[Symbol.iterator](): Generator<Either<L, R>, R, R> {
319
+ return this.value
320
+ }
321
+
322
+ // This mirrors the sync iterator exactly; async consumers could fall back to
323
+ // Symbol.iterator, but the explicit async form keeps the contract obvious.
324
+ async *[Symbol.asyncIterator](): AsyncGenerator<Either<L, R>, R, unknown> {
325
+ await Promise.resolve()
326
+ return this.value
327
+ }
328
+ }
329
+
330
+ export const isEither = <L, R>(target: unknown): target is Either<L, R> => {
331
+ return Either.isEither(target)
332
+ }
333
+
334
+ export const isLeft = <L, R>(target: unknown): target is Left<L, R> => {
335
+ return Left.isLeft(target)
336
+ }
337
+
338
+ export const isRight = <L, R>(target: unknown): target is Right<L, R> => {
339
+ return Right.isRight(target)
340
+ }
341
+
342
+ type LeftFunction = {
343
+ <L>(value: L): Either<L, never>
344
+ <L, R>(value: L): Either<L, R>
345
+ }
346
+ export const left = (<L, R>(value: L): Either<L, R> => {
347
+ return Either.left<L, R>(value)
348
+ }) as LeftFunction
349
+
350
+ type RightFunction = {
351
+ <R>(value: R): Either<never, R>
352
+ <L, R>(value: R): Either<L, R>
185
353
  }
354
+ export const right = (<L, R>(value: R): Either<L, R> => {
355
+ return Either.right<L, R>(value)
356
+ }) as RightFunction
186
357
 
187
358
  export type TupleOfEither<Left, Right> = [undefined, Right] | [Left, undefined]
188
359
  export const eitherToTuple = <L, R>(either: Either<L, R>): TupleOfEither<L, R> => {
189
360
  const left = either.isLeft() ? either.getLeft() : undefined
190
361
  const right = either.isRight() ? either.getRight() : undefined
191
- // oxlint-disable-next-line typescript/no-unsafe-type-assertion
192
362
  return [left, right] as TupleOfEither<L, R>
193
363
  }