@effect-app/vue 4.0.0-beta.22 → 4.0.0-beta.220

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 (103) hide show
  1. package/CHANGELOG.md +1605 -0
  2. package/dist/commander.d.ts +628 -0
  3. package/dist/commander.d.ts.map +1 -0
  4. package/dist/commander.js +1060 -0
  5. package/dist/confirm.d.ts +19 -0
  6. package/dist/confirm.d.ts.map +1 -0
  7. package/dist/confirm.js +24 -0
  8. package/dist/errorReporter.d.ts +4 -4
  9. package/dist/errorReporter.d.ts.map +1 -1
  10. package/dist/errorReporter.js +12 -18
  11. package/dist/form.d.ts +14 -5
  12. package/dist/form.d.ts.map +1 -1
  13. package/dist/form.js +41 -12
  14. package/dist/index.d.ts +1 -1
  15. package/dist/intl.d.ts +15 -0
  16. package/dist/intl.d.ts.map +1 -0
  17. package/dist/intl.js +9 -0
  18. package/dist/lib.d.ts +6 -9
  19. package/dist/lib.d.ts.map +1 -1
  20. package/dist/lib.js +35 -10
  21. package/dist/makeClient.d.ts +152 -339
  22. package/dist/makeClient.d.ts.map +1 -1
  23. package/dist/makeClient.js +221 -376
  24. package/dist/makeContext.d.ts +1 -1
  25. package/dist/makeContext.d.ts.map +1 -1
  26. package/dist/makeIntl.d.ts +1 -1
  27. package/dist/makeIntl.d.ts.map +1 -1
  28. package/dist/makeUseCommand.d.ts +8 -0
  29. package/dist/makeUseCommand.d.ts.map +1 -0
  30. package/dist/makeUseCommand.js +13 -0
  31. package/dist/mutate.d.ts +52 -34
  32. package/dist/mutate.d.ts.map +1 -1
  33. package/dist/mutate.js +137 -46
  34. package/dist/query.d.ts +19 -39
  35. package/dist/query.d.ts.map +1 -1
  36. package/dist/query.js +128 -72
  37. package/dist/routeParams.d.ts +1 -1
  38. package/dist/runtime.d.ts +7 -4
  39. package/dist/runtime.d.ts.map +1 -1
  40. package/dist/runtime.js +27 -17
  41. package/dist/toast.d.ts +50 -0
  42. package/dist/toast.d.ts.map +1 -0
  43. package/dist/toast.js +32 -0
  44. package/dist/withToast.d.ts +27 -0
  45. package/dist/withToast.d.ts.map +1 -0
  46. package/dist/withToast.js +59 -0
  47. package/examples/streamMutation.ts +70 -0
  48. package/package.json +48 -50
  49. package/src/commander.ts +3393 -0
  50. package/src/{experimental/confirm.ts → confirm.ts} +10 -14
  51. package/src/errorReporter.ts +62 -74
  52. package/src/form.ts +56 -17
  53. package/src/intl.ts +12 -0
  54. package/src/lib.ts +47 -20
  55. package/src/makeClient.ts +568 -1134
  56. package/src/{experimental/makeUseCommand.ts → makeUseCommand.ts} +6 -4
  57. package/src/mutate.ts +265 -127
  58. package/src/query.ts +197 -183
  59. package/src/runtime.ts +41 -20
  60. package/src/{experimental/toast.ts → toast.ts} +13 -27
  61. package/src/{experimental/withToast.ts → withToast.ts} +40 -12
  62. package/test/Mutation.test.ts +176 -23
  63. package/test/dist/form.test.d.ts.map +1 -1
  64. package/test/dist/lib.test.d.ts.map +1 -0
  65. package/test/dist/streamFinal.test.d.ts.map +1 -0
  66. package/test/dist/streamFn.test.d.ts.map +1 -0
  67. package/test/dist/stubs.d.ts +3529 -122
  68. package/test/dist/stubs.d.ts.map +1 -1
  69. package/test/dist/stubs.js +182 -31
  70. package/test/form-validation-errors.test.ts +23 -19
  71. package/test/form.test.ts +20 -2
  72. package/test/lib.test.ts +240 -0
  73. package/test/makeClient.test.ts +292 -38
  74. package/test/streamFinal.test.ts +63 -0
  75. package/test/streamFn.test.ts +455 -0
  76. package/test/stubs.ts +218 -42
  77. package/tsconfig.examples.json +20 -0
  78. package/tsconfig.json +0 -1
  79. package/tsconfig.json.bak +5 -2
  80. package/tsconfig.src.json +34 -34
  81. package/tsconfig.test.json +2 -2
  82. package/vitest.config.ts +5 -5
  83. package/dist/experimental/commander.d.ts +0 -359
  84. package/dist/experimental/commander.d.ts.map +0 -1
  85. package/dist/experimental/commander.js +0 -557
  86. package/dist/experimental/confirm.d.ts +0 -19
  87. package/dist/experimental/confirm.d.ts.map +0 -1
  88. package/dist/experimental/confirm.js +0 -28
  89. package/dist/experimental/intl.d.ts +0 -16
  90. package/dist/experimental/intl.d.ts.map +0 -1
  91. package/dist/experimental/intl.js +0 -5
  92. package/dist/experimental/makeUseCommand.d.ts +0 -8
  93. package/dist/experimental/makeUseCommand.d.ts.map +0 -1
  94. package/dist/experimental/makeUseCommand.js +0 -13
  95. package/dist/experimental/toast.d.ts +0 -47
  96. package/dist/experimental/toast.d.ts.map +0 -1
  97. package/dist/experimental/toast.js +0 -41
  98. package/dist/experimental/withToast.d.ts +0 -25
  99. package/dist/experimental/withToast.d.ts.map +0 -1
  100. package/dist/experimental/withToast.js +0 -45
  101. package/eslint.config.mjs +0 -24
  102. package/src/experimental/commander.ts +0 -1835
  103. package/src/experimental/intl.ts +0 -9
@@ -1,1835 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { asResult, type MissingDependencies, reportRuntimeError } from "@effect-app/vue"
3
- import { reportMessage } from "@effect-app/vue/errorReporter"
4
- import { Cause, Effect, type Exit, type Fiber, flow, Layer, Match, MutableHashMap, Option, Predicate, S, ServiceMap } from "effect-app"
5
- import { SupportedErrors } from "effect-app/client"
6
- import { OperationFailure, OperationSuccess } from "effect-app/Operations"
7
- import { isGeneratorFunction, wrapEffect } from "effect-app/utils"
8
- import { type AsyncResult } from "effect/unstable/reactivity/AsyncResult"
9
- import { type FormatXMLElementFn, type PrimitiveType } from "intl-messageformat"
10
- import { computed, type ComputedRef, reactive, ref } from "vue"
11
- import { Confirm } from "./confirm.js"
12
- import { I18n } from "./intl.js"
13
- import { WithToast } from "./withToast.js"
14
-
15
- type IntlRecord = Record<string, PrimitiveType | FormatXMLElementFn<string, string>>
16
- type FnOptions<Id extends string, I18nCustomKey extends string, State extends IntlRecord | undefined> = {
17
- i18nCustomKey?: I18nCustomKey
18
- /**
19
- * passed to the i18n formatMessage calls so you can use it in translation messagee
20
- * including the Command `action` string.
21
- * Automatically wrapped with Computed if just a thunk.
22
- * provided as Command.state tag, so you can access it in the function.
23
- */
24
- state?: ComputedRef<State> | (() => State)
25
- // TODO: namespaced keys like reactivity keys: ["modify_thing", item], so that one can block also on "modify_thing" *
26
- blockKey?: (id: Id) => string | undefined
27
- waitKey?: (id: Id) => string | undefined
28
- allowed?: (id: Id, state: ComputedRef<State>) => boolean
29
- }
30
-
31
- type FnOptionsInternal<I18nCustomKey extends string> = {
32
- i18nCustomKey?: I18nCustomKey | undefined
33
- state?: IntlRecord | undefined
34
- }
35
-
36
- export const DefaultIntl = {
37
- de: {
38
- "handle.confirmation": "{action} bestätigen?",
39
- "handle.waiting": "{action} wird ausgeführt...",
40
- "handle.success": "{action} erfolgreich",
41
- "handle.with_errors": "{action} fehlgeschlagen",
42
- "handle.with_warnings": "{action} erfolgreich, mit Warnungen",
43
- "handle.error_response":
44
- "Die Anfrage war nicht erfolgreich:\n{error}\nWir wurden benachrichtigt und werden das Problem in Kürze beheben.",
45
- "handle.response_error": "Die Antwort konnte nicht verarbeitet werden:\n{error}",
46
- "handle.request_error": "Die Anfrage konnte nicht gesendet werden:\n{error}",
47
- "handle.unexpected_error2": "{action} unerwarteter Fehler, probieren sie es in kurze nochmals.",
48
-
49
- "handle.unexpected_error": "Unerwarteter Fehler:\n{error}",
50
- "handle.not_found": "Das gesuchte war nicht gefunden"
51
- },
52
- en: {
53
- "handle.confirmation": "Confirm {action}?",
54
- "handle.waiting": "{action} executing...",
55
- "handle.success": "{action} Success",
56
- "handle.with_errors": "{action} Failed",
57
- "handle.with_warnings": "{action}, with warnings",
58
- "handle.error_response":
59
- "There was an error in processing the response:\n{error}\nWe have been notified and will fix the problem shortly.",
60
- "handle.request_error": "There was an error in the request:\n{error}",
61
- "handle.response_error": "The request was not successful:\n{error}",
62
- "handle.unexpected_error2": "{action} unexpected error, please try again shortly.",
63
-
64
- "handle.unexpected_error": "Unexpected Error:\n{error}",
65
- "handle.not_found": "The requested item was not found."
66
- }
67
- }
68
-
69
- export class CommandContext extends ServiceMap.Service<CommandContext, {
70
- id: string
71
- i18nKey: string
72
- action: string
73
- label: string
74
- namespace: string
75
- namespaced: (key: string) => string
76
- state?: IntlRecord | undefined
77
- }>()(
78
- "CommandContext"
79
- ) {}
80
-
81
- export type EmitWithCallback<A, Event extends string> = (event: Event, value: A, onDone: () => void) => void
82
-
83
- /**
84
- * Use to wrap emit calls with a callback to signal completion.
85
- * Useful when the publisher wants to wait for the subscriber to finish processing.
86
- */
87
- export const wrapEmit = <A, Event extends string>(
88
- emit: EmitWithCallback<A, NoInfer<Event>>,
89
- event: Event
90
- ) =>
91
- (value: A) => new Promise<void>((resolve) => emit(event, value, resolve))
92
-
93
- export declare namespace Commander {
94
- export type CommanderBase<RT, Id extends string, I18nKey extends string, State extends IntlRecord | undefined> =
95
- & Gen<RT, Id, I18nKey, State>
96
- & NonGen<RT, Id, I18nKey, State>
97
- & CommandContextLocal<Id, I18nKey>
98
- & {
99
- state: ServiceMap.Service<`Commander.Command.${Id}.state`, State>
100
- }
101
-
102
- export type CommanderFn<RT, Id extends string, I18nKey extends string, State extends IntlRecord | undefined> =
103
- CommanderBase<RT, Id, I18nKey, State>
104
-
105
- export type CommanderWrap<
106
- RT,
107
- Id extends string,
108
- I18nCustomKey extends string,
109
- State extends IntlRecord | undefined,
110
- I,
111
- A,
112
- E,
113
- R
114
- > =
115
- & CommandContextLocal<Id, I18nCustomKey>
116
- & GenWrap<RT, Id, I18nCustomKey, I, A, E, R, State>
117
- & NonGenWrap<RT, Id, I18nCustomKey, I, A, E, R, State>
118
- & {
119
- state: ServiceMap.Service<`Commander.Command.${Id}.state`, State>
120
- }
121
-
122
- export interface CommandContextLocal<Id extends string, I18nKey extends string> {
123
- id: Id
124
- i18nKey: I18nKey
125
- namespace: `action.${I18nKey}`
126
- namespaced: <K extends string>(k: K) => `action.${I18nKey}.${K}`
127
- }
128
-
129
- export interface CommandProps<
130
- A,
131
- E,
132
- Id extends string,
133
- I18nKey extends string,
134
- State extends IntlRecord | undefined
135
- > extends CommandContextLocal<Id, I18nKey> {
136
- /** reactive */
137
- action: string
138
- /** reactive */
139
- label: string
140
- /** reactive */
141
- result: AsyncResult<A, E>
142
- /** reactive */
143
- waiting: boolean
144
- /** reactive */
145
- blocked: boolean
146
- /** reactive */
147
- allowed: boolean
148
- /** reactive */
149
- state: State
150
- }
151
-
152
- export interface CommandOut<
153
- Arg,
154
- A,
155
- E,
156
- R,
157
- Id extends string,
158
- I18nKey extends string,
159
- State extends IntlRecord | undefined
160
- > extends CommandProps<A, E, Id, I18nKey, State> {
161
- new(): {}
162
-
163
- /** click handlers */
164
- handle: ((arg: Arg) => Fiber.Fiber<Exit.Exit<A, E>, never>) & {
165
- /** @deprecated don't exist */
166
- effect: (arg: Arg) => Effect.Effect<A, E, R>
167
- }
168
-
169
- // // TODO: if we keep them, it would probably be nicer as an option api, deciding the return value like in Atom?
170
- // /** @experimental */
171
- // compose: (arg: Arg) => Effect.Effect<Exit.Exit<A, E>, R>
172
- // /** @experimental */
173
- // compose2: (arg: Arg) => Effect.Effect<A, E, R>
174
- // /**
175
- // * @experimental
176
- // * captures the current span and returns an Effect that when run will execute the command
177
- // */
178
- // handleEffect: (arg: Arg) => Effect.Effect<Fiber.Fiber<Exit.Exit<A, E>, never>>
179
- // /**
180
- // * @experimental
181
- // */
182
- // exec: (arg: Arg) => Effect.Effect<Exit.Exit<A, E>, never, Exclude<R, CommandContext>>
183
- }
184
-
185
- export interface CommandContextLocal2<Id extends string, I18nKey extends string, State extends IntlRecord | undefined>
186
- extends CommandContextLocal<Id, I18nKey>
187
- {
188
- state: State
189
- }
190
-
191
- type CommandOutHelper<
192
- Arg,
193
- Eff extends Effect.Effect<any, any, any>,
194
- Id extends string,
195
- I18nKey extends string,
196
- State extends IntlRecord | undefined
197
- > = CommandOut<
198
- Arg,
199
- Effect.Success<Eff>,
200
- Effect.Error<Eff>,
201
- Effect.Services<Eff>,
202
- Id,
203
- I18nKey,
204
- State
205
- >
206
-
207
- export type Gen<RT, Id extends string, I18nKey extends string, State extends IntlRecord | undefined> = {
208
- <
209
- Eff extends Effect.Yieldable<any, any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
210
- AEff,
211
- Arg = void
212
- >(
213
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => Generator<Eff, AEff, never>
214
- ): CommandOut<
215
- Arg,
216
- AEff,
217
- [Eff] extends [never] ? never
218
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer E, infer _R>] ? E
219
- : never,
220
- [Eff] extends [never] ? never
221
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer _E, infer R>] ? R
222
- : never,
223
- Id,
224
- I18nKey,
225
- State
226
- >
227
- <
228
- Eff extends Effect.Yieldable<any, any, any, any>,
229
- AEff,
230
- A extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
231
- Arg = void
232
- >(
233
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => Generator<Eff, AEff, never>,
234
- a: (
235
- _: Effect.Effect<
236
- AEff,
237
- [Eff] extends [never] ? never
238
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer E, infer _R>] ? E
239
- : never,
240
- [Eff] extends [never] ? never
241
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer _E, infer R>] ? R
242
- : never
243
- >,
244
- arg: NoInfer<Arg>,
245
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
246
- ) => A
247
- ): CommandOutHelper<Arg, A, Id, I18nKey, State>
248
- <
249
- Eff extends Effect.Yieldable<any, any, any, any>,
250
- AEff,
251
- A,
252
- B extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
253
- Arg = void
254
- >(
255
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => Generator<Eff, AEff, never>,
256
- a: (
257
- _: Effect.Effect<
258
- AEff,
259
- [Eff] extends [never] ? never
260
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer E, infer _R>] ? E
261
- : never,
262
- [Eff] extends [never] ? never
263
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer _E, infer R>] ? R
264
- : never
265
- >,
266
- arg: NoInfer<Arg>,
267
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
268
- ) => A,
269
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B
270
- ): CommandOutHelper<Arg, B, Id, I18nKey, State>
271
- <
272
- Eff extends Effect.Yieldable<any, any, any, any>,
273
- AEff,
274
- A,
275
- B,
276
- C extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
277
- Arg = void
278
- >(
279
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => Generator<Eff, AEff, never>,
280
- a: (
281
- _: Effect.Effect<
282
- AEff,
283
- [Eff] extends [never] ? never
284
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer E, infer _R>] ? E
285
- : never,
286
- [Eff] extends [never] ? never
287
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer _E, infer R>] ? R
288
- : never
289
- >,
290
- arg: NoInfer<Arg>,
291
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
292
- ) => A,
293
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
294
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C
295
- ): CommandOutHelper<Arg, C, Id, I18nKey, State>
296
- <
297
- Eff extends Effect.Yieldable<any, any, any, any>,
298
- AEff,
299
- A,
300
- B,
301
- C,
302
- D extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
303
- Arg = void
304
- >(
305
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => Generator<Eff, AEff, never>,
306
- a: (
307
- _: Effect.Effect<
308
- AEff,
309
- [Eff] extends [never] ? never
310
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer E, infer _R>] ? E
311
- : never,
312
- [Eff] extends [never] ? never
313
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer _E, infer R>] ? R
314
- : never
315
- >,
316
- arg: NoInfer<Arg>,
317
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
318
- ) => A,
319
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
320
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
321
- d: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D
322
- ): CommandOutHelper<Arg, D, Id, I18nKey, State>
323
- <
324
- Eff extends Effect.Yieldable<any, any, any, any>,
325
- AEff,
326
- A,
327
- B,
328
- C,
329
- D,
330
- E extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
331
- Arg = void
332
- >(
333
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => Generator<Eff, AEff, never>,
334
- a: (
335
- _: Effect.Effect<
336
- AEff,
337
- [Eff] extends [never] ? never
338
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer E, infer _R>] ? E
339
- : never,
340
- [Eff] extends [never] ? never
341
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer _E, infer R>] ? R
342
- : never
343
- >,
344
- arg: NoInfer<Arg>,
345
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
346
- ) => A,
347
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
348
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
349
- d: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
350
- e: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E
351
- ): CommandOutHelper<Arg, E, Id, I18nKey, State>
352
- <
353
- Eff extends Effect.Yieldable<any, any, any, any>,
354
- AEff,
355
- A,
356
- B,
357
- C,
358
- D,
359
- E,
360
- F extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
361
- Arg = void
362
- >(
363
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => Generator<Eff, AEff, never>,
364
- a: (
365
- _: Effect.Effect<
366
- AEff,
367
- [Eff] extends [never] ? never
368
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer E, infer _R>] ? E
369
- : never,
370
- [Eff] extends [never] ? never
371
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer _E, infer R>] ? R
372
- : never
373
- >,
374
- arg: NoInfer<Arg>,
375
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
376
- ) => A,
377
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
378
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
379
- d: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
380
- e: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
381
- f: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F
382
- ): CommandOutHelper<Arg, F, Id, I18nKey, State>
383
- <
384
- Eff extends Effect.Yieldable<any, any, any, any>,
385
- AEff,
386
- A,
387
- B,
388
- C,
389
- D,
390
- E,
391
- F,
392
- G extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
393
- Arg = void
394
- >(
395
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => Generator<Eff, AEff, never>,
396
- a: (
397
- _: Effect.Effect<
398
- AEff,
399
- [Eff] extends [never] ? never
400
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer E, infer _R>] ? E
401
- : never,
402
- [Eff] extends [never] ? never
403
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer _E, infer R>] ? R
404
- : never
405
- >,
406
- arg: NoInfer<Arg>,
407
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
408
- ) => A,
409
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
410
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
411
- d: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
412
- e: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
413
- f: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
414
- g: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => G
415
- ): CommandOutHelper<Arg, G, Id, I18nKey, State>
416
- <
417
- Eff extends Effect.Yieldable<any, any, any, any>,
418
- AEff,
419
- A,
420
- B,
421
- C,
422
- D,
423
- E,
424
- F,
425
- G,
426
- H extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
427
- Arg = void
428
- >(
429
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => Generator<Eff, AEff, never>,
430
- a: (
431
- _: Effect.Effect<
432
- AEff,
433
- [Eff] extends [never] ? never
434
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer E, infer _R>] ? E
435
- : never,
436
- [Eff] extends [never] ? never
437
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer _E, infer R>] ? R
438
- : never
439
- >,
440
- arg: NoInfer<Arg>,
441
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
442
- ) => A,
443
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
444
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
445
- d: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
446
- e: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
447
- f: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
448
- g: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => G,
449
- h: (_: G, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => H
450
- ): CommandOutHelper<Arg, H, Id, I18nKey, State>
451
- <
452
- Eff extends Effect.Yieldable<any, any, any, any>,
453
- AEff,
454
- A,
455
- B,
456
- C,
457
- D,
458
- E,
459
- F,
460
- G,
461
- H,
462
- I extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
463
- Arg = void
464
- >(
465
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => Generator<Eff, AEff, never>,
466
- a: (
467
- _: Effect.Effect<
468
- AEff,
469
- [Eff] extends [never] ? never
470
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer E, infer _R>] ? E
471
- : never,
472
- [Eff] extends [never] ? never
473
- : [Eff] extends [Effect.Yieldable<any, infer _A, infer _E, infer R>] ? R
474
- : never
475
- >,
476
- arg: NoInfer<Arg>,
477
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
478
- ) => A,
479
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
480
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
481
- d: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
482
- e: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
483
- f: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
484
- g: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => G,
485
- h: (_: G, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => H,
486
- i: (_: H, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => I
487
- ): CommandOutHelper<Arg, I, Id, I18nKey, State>
488
- }
489
-
490
- export type NonGen<RT, Id extends string, I18nKey extends string, State extends IntlRecord | undefined> = {
491
- <
492
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
493
- Arg = void
494
- >(
495
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => Eff
496
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
497
- <
498
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
499
- A,
500
- Arg = void
501
- >(
502
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => A,
503
- a: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
504
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
505
- <
506
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
507
- A,
508
- B,
509
- Arg = void
510
- >(
511
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => A,
512
- a: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
513
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
514
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
515
- <
516
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
517
- A,
518
- B,
519
- C,
520
- Arg = void
521
- >(
522
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => A,
523
- a: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
524
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
525
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
526
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
527
- <
528
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
529
- A,
530
- B,
531
- C,
532
- D,
533
- Arg = void
534
- >(
535
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => A,
536
- a: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
537
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
538
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
539
- d: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
540
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
541
- <
542
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
543
- A,
544
- B,
545
- C,
546
- D,
547
- E,
548
- Arg = void
549
- >(
550
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => A,
551
- a: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
552
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
553
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
554
- d: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
555
- e: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
556
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
557
- <
558
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
559
- A,
560
- B,
561
- C,
562
- D,
563
- E,
564
- F,
565
- Arg = void
566
- >(
567
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => A,
568
- a: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
569
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
570
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
571
- d: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
572
- e: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
573
- f: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
574
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
575
- <
576
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
577
- A,
578
- B,
579
- C,
580
- D,
581
- E,
582
- F,
583
- G,
584
- Arg = void
585
- >(
586
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => A,
587
- a: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
588
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
589
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
590
- d: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
591
- e: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
592
- f: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => G,
593
- g: (_: G, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
594
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
595
- <
596
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
597
- A,
598
- B,
599
- C,
600
- D,
601
- E,
602
- F,
603
- G,
604
- H,
605
- Arg = void
606
- >(
607
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => A,
608
- a: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
609
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
610
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
611
- d: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
612
- e: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
613
- f: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => G,
614
- g: (_: G, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => H,
615
- h: (_: H, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
616
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
617
- <
618
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
619
- A,
620
- B,
621
- C,
622
- D,
623
- E,
624
- F,
625
- G,
626
- H,
627
- I,
628
- Arg = void
629
- >(
630
- body: (arg: Arg, ctx: CommandContextLocal2<Id, I18nKey, State>) => A,
631
- a: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
632
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
633
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
634
- d: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
635
- e: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
636
- f: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => G,
637
- g: (_: G, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => H,
638
- h: (_: H, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => I,
639
- i: (_: H, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
640
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
641
- }
642
-
643
- export type GenWrap<
644
- RT,
645
- Id extends string,
646
- I18nKey extends string,
647
- Arg,
648
- AEff,
649
- EEff,
650
- REff,
651
- State extends IntlRecord | undefined
652
- > = {
653
- (): Exclude<REff, RT> extends never ? CommandOut<
654
- Arg,
655
- AEff,
656
- EEff,
657
- REff,
658
- Id,
659
- I18nKey,
660
- State
661
- >
662
- : MissingDependencies<RT, REff> & {}
663
- <
664
- A extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>
665
- >(
666
- a: (
667
- _: Effect.Effect<
668
- AEff,
669
- EEff,
670
- REff
671
- >,
672
- arg: NoInfer<Arg>,
673
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
674
- ) => A
675
- ): CommandOutHelper<Arg, A, Id, I18nKey, State>
676
- <
677
- A,
678
- B extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>
679
- >(
680
- a: (
681
- _: Effect.Effect<
682
- AEff,
683
- EEff,
684
- REff
685
- >,
686
- arg: NoInfer<Arg>,
687
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
688
- ) => A,
689
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B
690
- ): CommandOutHelper<Arg, B, Id, I18nKey, State>
691
- <
692
- A,
693
- B,
694
- C extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>
695
- >(
696
- a: (
697
- _: Effect.Effect<
698
- AEff,
699
- EEff,
700
- REff
701
- >,
702
- arg: NoInfer<Arg>,
703
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
704
- ) => A,
705
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
706
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C
707
- ): CommandOutHelper<Arg, C, Id, I18nKey, State>
708
- <
709
- A,
710
- B,
711
- C,
712
- D extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>
713
- >(
714
- a: (
715
- _: Effect.Effect<
716
- AEff,
717
- EEff,
718
- REff
719
- >,
720
- arg: NoInfer<Arg>,
721
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
722
- ) => A,
723
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
724
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
725
- d: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D
726
- ): CommandOutHelper<Arg, D, Id, I18nKey, State>
727
- <
728
- A,
729
- B,
730
- C,
731
- D,
732
- E extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>
733
- >(
734
- a: (
735
- _: Effect.Effect<
736
- AEff,
737
- EEff,
738
- REff
739
- >,
740
- arg: NoInfer<Arg>,
741
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
742
- ) => A,
743
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
744
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
745
- d: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
746
- e: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E
747
- ): CommandOutHelper<Arg, E, Id, I18nKey, State>
748
- <
749
- A,
750
- B,
751
- C,
752
- D,
753
- E,
754
- F extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>
755
- >(
756
- a: (
757
- _: Effect.Effect<
758
- AEff,
759
- EEff,
760
- REff
761
- >,
762
- arg: NoInfer<Arg>,
763
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
764
- ) => A,
765
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
766
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
767
- d: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
768
- e: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
769
- f: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F
770
- ): CommandOutHelper<Arg, F, Id, I18nKey, State>
771
- <
772
- A,
773
- B,
774
- C,
775
- D,
776
- E,
777
- F,
778
- G extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>
779
- >(
780
- a: (
781
- _: Effect.Effect<
782
- AEff,
783
- EEff,
784
- REff
785
- >,
786
- arg: NoInfer<Arg>,
787
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
788
- ) => A,
789
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
790
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
791
- d: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
792
- e: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
793
- f: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
794
- g: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => G
795
- ): CommandOutHelper<Arg, G, Id, I18nKey, State>
796
- <A, B, C, D, E, F, G, H extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>>(
797
- a: (
798
- _: Effect.Effect<
799
- AEff,
800
- EEff,
801
- REff
802
- >,
803
- arg: NoInfer<Arg>,
804
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
805
- ) => A,
806
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
807
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
808
- d: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
809
- e: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
810
- f: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
811
- g: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => G,
812
- h: (_: G, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => H
813
- ): CommandOutHelper<Arg, H, Id, I18nKey, State>
814
- <A, B, C, D, E, F, G, H, I extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>>(
815
- a: (
816
- _: Effect.Effect<
817
- AEff,
818
- EEff,
819
- REff
820
- >,
821
- arg: NoInfer<Arg>,
822
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
823
- ) => A,
824
- b: (_: A, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => B,
825
- c: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
826
- d: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
827
- e: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
828
- f: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
829
- g: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => G,
830
- h: (_: G, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => H,
831
- i: (_: H, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => I
832
- ): CommandOutHelper<Arg, I, Id, I18nKey, State>
833
- }
834
-
835
- export type NonGenWrap<
836
- RT,
837
- Id extends string,
838
- I18nKey extends string,
839
- Arg,
840
- AEff,
841
- EEff,
842
- REff,
843
- State extends IntlRecord | undefined
844
- > = {
845
- (): Exclude<REff, RT> extends never ? CommandOutHelper<Arg, Effect.Effect<AEff, EEff, REff>, Id, I18nKey, State>
846
- : MissingDependencies<RT, REff> & {}
847
- <
848
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
849
- Arg
850
- >(
851
- a: (
852
- _: Effect.Effect<
853
- AEff,
854
- EEff,
855
- REff
856
- >,
857
- arg: NoInfer<Arg>,
858
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
859
- ) => Eff
860
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
861
- <
862
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
863
- B,
864
- Arg
865
- >(
866
- a: (
867
- _: Effect.Effect<
868
- AEff,
869
- EEff,
870
- REff
871
- >,
872
- arg: NoInfer<Arg>,
873
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
874
- ) => B,
875
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
876
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
877
- <
878
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
879
- B,
880
- C,
881
- Arg
882
- >(
883
- a: (
884
- _: Effect.Effect<
885
- AEff,
886
- EEff,
887
- REff
888
- >,
889
- arg: NoInfer<Arg>,
890
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
891
- ) => B,
892
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
893
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
894
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
895
- <
896
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
897
- B,
898
- C,
899
- D,
900
- Arg
901
- >(
902
- a: (
903
- _: Effect.Effect<
904
- AEff,
905
- EEff,
906
- REff
907
- >,
908
- arg: NoInfer<Arg>,
909
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
910
- ) => B,
911
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
912
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
913
- d: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
914
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
915
- <
916
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
917
- B,
918
- C,
919
- D,
920
- E,
921
- Arg
922
- >(
923
- a: (
924
- _: Effect.Effect<
925
- AEff,
926
- EEff,
927
- REff
928
- >,
929
- arg: NoInfer<Arg>,
930
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
931
- ) => B,
932
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
933
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
934
- d: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
935
- e: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
936
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
937
- <
938
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
939
- B,
940
- C,
941
- D,
942
- E,
943
- F,
944
- Arg
945
- >(
946
- a: (
947
- _: Effect.Effect<
948
- AEff,
949
- EEff,
950
- REff
951
- >,
952
- arg: NoInfer<Arg>,
953
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
954
- ) => B,
955
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
956
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
957
- d: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
958
- e: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
959
- f: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
960
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
961
- <
962
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
963
- B,
964
- C,
965
- D,
966
- E,
967
- F,
968
- G,
969
- Arg
970
- >(
971
- a: (
972
- _: Effect.Effect<
973
- AEff,
974
- EEff,
975
- REff
976
- >,
977
- arg: NoInfer<Arg>,
978
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
979
- ) => B,
980
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
981
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
982
- d: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
983
- e: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
984
- f: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => G,
985
- g: (_: G, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
986
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
987
- <
988
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
989
- B,
990
- C,
991
- D,
992
- E,
993
- F,
994
- G,
995
- H,
996
- Arg
997
- >(
998
- a: (
999
- _: Effect.Effect<
1000
- AEff,
1001
- EEff,
1002
- REff
1003
- >,
1004
- arg: NoInfer<Arg>,
1005
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
1006
- ) => B,
1007
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
1008
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
1009
- d: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
1010
- e: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
1011
- f: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => G,
1012
- g: (_: G, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => H,
1013
- h: (_: H, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
1014
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
1015
- <
1016
- Eff extends Effect.Effect<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>,
1017
- B,
1018
- C,
1019
- D,
1020
- E,
1021
- F,
1022
- G,
1023
- H,
1024
- I,
1025
- Arg
1026
- >(
1027
- a: (
1028
- _: Effect.Effect<
1029
- AEff,
1030
- EEff,
1031
- REff
1032
- >,
1033
- arg: NoInfer<Arg>,
1034
- ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
1035
- ) => B,
1036
- b: (_: B, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => C,
1037
- c: (_: C, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => D,
1038
- d: (_: D, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => E,
1039
- e: (_: E, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => F,
1040
- f: (_: F, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => G,
1041
- g: (_: G, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => H,
1042
- h: (_: H, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => I,
1043
- i: (_: H, arg: NoInfer<Arg>, ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>) => Eff
1044
- ): CommandOutHelper<Arg, Eff, Id, I18nKey, State>
1045
- }
1046
- }
1047
-
1048
- type ErrorRenderer<E, Args extends readonly any[]> = (e: E, action: string, ...args: Args) => string | undefined
1049
-
1050
- const renderErrorMaker = I18n.useSync(
1051
- ({ intl }) =>
1052
- <E, Args extends readonly any[]>(action: string, errorRenderer?: ErrorRenderer<E, Args>) =>
1053
- (e: E, ...args: Args): string => {
1054
- if (errorRenderer) {
1055
- const m = errorRenderer(e, action, ...args)
1056
- if (m !== undefined) {
1057
- return m
1058
- }
1059
- }
1060
- if (!S.is(SupportedErrors)(e) && !S.isSchemaError(e)) {
1061
- if (typeof e === "object" && e !== null) {
1062
- if ("message" in e) {
1063
- return `${e.message}`
1064
- }
1065
- if ("_tag" in e) {
1066
- return `${e._tag}`
1067
- }
1068
- }
1069
- return ""
1070
- }
1071
- const e2: SupportedErrors | S.SchemaError = e
1072
- return Match.value(e2).pipe(
1073
- Match.tags({
1074
- NotFoundError: (e) => {
1075
- return intl.formatMessage({ id: "handle.not_found" }, { type: e.type, id: e.id })
1076
- },
1077
- SchemaError: (e) => {
1078
- console.warn(e.toString())
1079
- return intl.formatMessage({ id: "validation.failed" })
1080
- }
1081
- }),
1082
- Match.orElse((e) => `${e.message ?? e._tag ?? e}`)
1083
- )
1084
- }
1085
- )
1086
-
1087
- const defaultFailureMessageHandler = <E, Args extends Array<unknown>, AME, AMR>(
1088
- actionMaker:
1089
- | string
1090
- | ((o: Option.Option<E>, ...args: Args) => string)
1091
- | ((o: Option.Option<E>, ...args: Args) => Effect.Effect<string, AME, AMR>),
1092
- errorRenderer?: ErrorRenderer<E, Args>
1093
- ) =>
1094
- Effect.fnUntraced(function*(o: Option.Option<E>, ...args: Args) {
1095
- const action = yield* wrapEffect(actionMaker)(o, ...args)
1096
- const { intl } = yield* I18n
1097
- const renderError = yield* renderErrorMaker
1098
-
1099
- return Option.match(o, {
1100
- onNone: () =>
1101
- intl.formatMessage(
1102
- { id: "handle.unexpected_error2" },
1103
- {
1104
- action,
1105
- error: "" // TODO consider again Cause.pretty(cause), // will be reported to Sentry/Otel anyway.. and we shouldn't bother users with error dumps?
1106
- }
1107
- ),
1108
- onSome: (e) =>
1109
- S.is(OperationFailure)(e)
1110
- ? {
1111
- level: "warn" as const,
1112
- message: intl.formatMessage(
1113
- { id: "handle.with_warnings" },
1114
- { action }
1115
- ) + e.message
1116
- ? "\n" + e.message
1117
- : ""
1118
- }
1119
- : `${
1120
- intl.formatMessage(
1121
- { id: "handle.with_errors" },
1122
- { action }
1123
- )
1124
- }:\n` + renderError(action, errorRenderer)(e, ...args)
1125
- })
1126
- })
1127
-
1128
- export const CommanderStatic = {
1129
- accessArgs: <In, Out, Arg2, Arg = void>(
1130
- cb: (a: NoInfer<Arg>, b: NoInfer<Arg2>) => (self: NoInfer<In>) => Out
1131
- ) =>
1132
- (self: In, arg: Arg, arg2: Arg2) => cb(arg, arg2)(self),
1133
-
1134
- /** Version of @see confirmOrInterrupt that automatically includes the action name in the default messages */
1135
- confirmOrInterrupt: Effect.fnUntraced(function*(
1136
- message: string | undefined = undefined
1137
- ) {
1138
- const context = yield* CommandContext
1139
- const { intl } = yield* I18n
1140
-
1141
- yield* Confirm.confirmOrInterrupt(
1142
- message
1143
- ?? intl.formatMessage(
1144
- { id: "handle.confirmation" },
1145
- { action: context.action }
1146
- )
1147
- )
1148
- }),
1149
- /** Version of @see confirm that automatically includes the action name in the default messages */
1150
- confirm: Effect.fnUntraced(function*(
1151
- message: string | undefined = undefined
1152
- ) {
1153
- const context = yield* CommandContext
1154
- const { intl } = yield* I18n
1155
- return yield* Confirm.confirm(
1156
- message
1157
- ?? intl.formatMessage(
1158
- { id: "handle.confirmation" },
1159
- { action: context.action }
1160
- )
1161
- )
1162
- }),
1163
- updateAction:
1164
- <Args extends Array<unknown>>(update: (currentActionId: string, ...args: Args) => string) =>
1165
- <A, E, R>(_: Effect.Effect<A, E, R>, ...input: Args) =>
1166
- Effect.updateService(
1167
- _,
1168
- CommandContext,
1169
- (c) => ({ ...c, action: update(c.action, ...input) })
1170
- ),
1171
- defaultFailureMessageHandler,
1172
- renderError: renderErrorMaker,
1173
- /**
1174
- * Version of withDefaultToast that automatically includes the action name in the default messages and uses intl.
1175
- * uses the Command id as i18n namespace. `action.{id}` is the main action name,
1176
- * and `action.{id}.waiting`, `action.{id}.success`, `action.{id}.failure` can be used to override the default messages for the respective states.
1177
- *
1178
- * the computed `state` provided to the Command can be used for interpolation in the i18n messages. (the state is captured at the start of each command execution and remains stable throughout)
1179
- *
1180
- * Note: if you provide `onWaiting` or `onSuccess` as `null`, no toast will be shown for that state.
1181
- * If you provide a string or function, it will be used instead of the i18n message.
1182
- * If you provide an `errorRenderer`, it will be used to render errors in the failure message.
1183
- */
1184
- withDefaultToast: <A, E, R, Args extends Array<unknown>>(
1185
- options?: {
1186
- /**
1187
- * if true, previous toasts with this key will be replaced
1188
- */
1189
- stableToastId?: undefined | true | string | ((id: string, ...args: Args) => true | string | undefined)
1190
- errorRenderer?: ErrorRenderer<E, Args>
1191
- onWaiting?: null | undefined | string | ((id: string, ...args: Args) => string | null | undefined)
1192
- onSuccess?: null | undefined | string | ((a: A, action: string, ...args: Args) => string | null | undefined)
1193
- }
1194
- ) =>
1195
- (
1196
- self: Effect.Effect<A, E, R>,
1197
- ...args: Args
1198
- ) =>
1199
- Effect.gen(function*() {
1200
- const cc = yield* CommandContext
1201
- const { intl } = yield* I18n
1202
- const withToast = yield* WithToast
1203
- const customWaiting = cc.namespaced("waiting")
1204
- const hasCustomWaiting = !!intl.messages[customWaiting]
1205
- const customSuccess = cc.namespaced("success")
1206
- const hasCustomSuccess = !!intl.messages[customSuccess]
1207
- const customFailure = cc.namespaced("failure")
1208
- const hasCustomFailure = !!intl.messages[customFailure]
1209
- const stableToastId = options?.stableToastId
1210
- ? typeof options.stableToastId === "string"
1211
- ? options.stableToastId
1212
- : typeof options.stableToastId === "boolean"
1213
- ? cc.id
1214
- : typeof options.stableToastId === "function"
1215
- ? (...args: Args) => {
1216
- const r = (options.stableToastId as any)(cc.id, ...args)
1217
- if (typeof r === "string") return r
1218
- if (r === true) return cc.id
1219
- return undefined
1220
- }
1221
- : undefined
1222
- : undefined
1223
- return yield* self.pipe(
1224
- (_) =>
1225
- withToast<A, E, Args, R, never, never, I18n>({
1226
- onWaiting: options?.onWaiting === null ? null : hasCustomWaiting
1227
- ? intl.formatMessage({
1228
- id: customWaiting
1229
- }, cc.state)
1230
- : intl.formatMessage(
1231
- { id: "handle.waiting" },
1232
- { action: cc.action }
1233
- ),
1234
- onSuccess: options?.onSuccess === null
1235
- ? null
1236
- : (a, ..._args) =>
1237
- hasCustomSuccess
1238
- ? intl.formatMessage(
1239
- { id: customSuccess },
1240
- cc.state
1241
- )
1242
- : (intl.formatMessage({ id: "handle.success" }, { action: cc.action })
1243
- + (S.is(OperationSuccess)(a) && a.message ? "\n" + a.message : "")),
1244
- onFailure: defaultFailureMessageHandler(
1245
- hasCustomFailure ? intl.formatMessage({ id: customFailure }, cc.state) : cc.action,
1246
- options?.errorRenderer
1247
- ),
1248
- stableToastId
1249
- })(_, ...args)
1250
- )
1251
- }),
1252
-
1253
- /** borrowing the idea from Families in Effect Atom */
1254
- family: <T extends object, Arg, ArgIn = Arg>(
1255
- maker: (arg: Arg) => T,
1256
- keyMaker?: (arg: ArgIn) => Arg
1257
- ): (arg: ArgIn) => T => {
1258
- const commands = MutableHashMap.empty<Arg, WeakRef<T>>()
1259
- const registry = new FinalizationRegistry<Arg>((arg) => {
1260
- MutableHashMap.remove(commands, arg)
1261
- })
1262
-
1263
- return (_k: ArgIn) => {
1264
- const k = keyMaker ? keyMaker(_k) : _k as unknown as Arg
1265
- // we want to compare structurally, unless custom equal/hash has been implemented
1266
- const item = MutableHashMap.get(commands, k).pipe(Option.flatMap((r) => Option.fromNullishOr(r.deref())))
1267
- if (item.value) {
1268
- return item.value
1269
- }
1270
- const v = maker(k)
1271
- MutableHashMap.set(commands, k, new WeakRef(v))
1272
-
1273
- registry.register(v, k)
1274
- return v
1275
- }
1276
- }
1277
- }
1278
-
1279
- const makeBaseInfo = <const Id extends string, const I18nKey extends string = Id>(
1280
- id: Id,
1281
- options?: Pick<FnOptionsInternal<I18nKey>, "i18nCustomKey">
1282
- ) => {
1283
- if (!id) throw new Error("must specify an id")
1284
- const i18nKey: I18nKey = options?.i18nCustomKey ?? id as unknown as I18nKey
1285
-
1286
- const namespace = `action.${i18nKey}` as const
1287
-
1288
- const context = {
1289
- id,
1290
- i18nKey,
1291
- namespace,
1292
- namespaced: <const K extends string>(k: K) => `${namespace}.${k}` as const
1293
- }
1294
-
1295
- return context
1296
- }
1297
-
1298
- const waitState = ref<Record<string, number>>({})
1299
- const registerWait = (id: string) => {
1300
- // console.debug("register wait", id)
1301
- waitState.value[id] = waitState.value[id] ? waitState.value[id] + 1 : 1
1302
- }
1303
- const unregisterWait = (id: string) => {
1304
- // console.debug("unregister wait", id)
1305
- if (waitState.value[id]) {
1306
- waitState.value[id] = waitState.value[id] - 1
1307
- if (waitState.value[id] <= 0) {
1308
- delete waitState.value[id]
1309
- }
1310
- }
1311
- }
1312
-
1313
- const getStateValues = <const Id extends string, const I18nKey extends string, State extends IntlRecord | undefined>(
1314
- options?: FnOptions<Id, I18nKey, State>
1315
- ): ComputedRef<State> => {
1316
- const state_ = options?.state
1317
- const state = !state_ ? computed(() => undefined as State) : typeof state_ === "function"
1318
- ? computed(state_)
1319
- : state_
1320
- return state
1321
- }
1322
-
1323
- // class preserves JSDoc throughout..
1324
- export class CommanderImpl<RT, RTHooks> {
1325
- constructor(
1326
- private readonly rt: ServiceMap.ServiceMap<RT>,
1327
- private readonly intl: I18n,
1328
- private readonly hooks: Layer.Layer<RTHooks, never, RT>
1329
- ) {
1330
- }
1331
-
1332
- readonly makeContext = <const Id extends string, const I18nKey extends string = Id>(
1333
- id: Id,
1334
- options?: FnOptionsInternal<I18nKey>
1335
- ) => {
1336
- if (!id) throw new Error("must specify an id")
1337
- const i18nKey: I18nKey = options?.i18nCustomKey ?? id as unknown as I18nKey
1338
-
1339
- const namespace = `action.${i18nKey}` as const
1340
-
1341
- // must remain stable through out single call
1342
- const action = this.intl.formatMessage({
1343
- id: namespace,
1344
- defaultMessage: id
1345
- }, { ...options?.state, _isLabel: false })
1346
-
1347
- const label = this.intl.formatMessage({
1348
- id: namespace,
1349
- defaultMessage: id
1350
- }, { ...options?.state, _isLabel: true })
1351
-
1352
- const context = CommandContext.of({
1353
- ...makeBaseInfo(id, options),
1354
- action,
1355
- label,
1356
- state: options?.state
1357
- })
1358
-
1359
- return context
1360
- }
1361
-
1362
- readonly makeCommand = <
1363
- const Id extends string,
1364
- const State extends IntlRecord | undefined,
1365
- const I18nKey extends string = Id
1366
- >(
1367
- id_: Id | { id: Id },
1368
- options?: FnOptions<Id, I18nKey, State>,
1369
- errorDef?: Error
1370
- ) => {
1371
- const id = typeof id_ === "string" ? id_ : id_.id
1372
- const state = getStateValues(options)
1373
-
1374
- return Object.assign(
1375
- <Arg, A, E, R extends RT | RTHooks | CommandContext | `Commander.Command.${Id}.state`>(
1376
- handler: (arg: Arg, ctx: Commander.CommandContextLocal2<Id, I18nKey, State>) => Effect.Effect<A, E, R>
1377
- ) => {
1378
- // we capture the definition stack here, so we can append it to later stack traces
1379
- const limit = Error.stackTraceLimit
1380
- Error.stackTraceLimit = 2
1381
- const localErrorDef = new Error()
1382
- Error.stackTraceLimit = limit
1383
- if (!errorDef) {
1384
- errorDef = localErrorDef
1385
- }
1386
-
1387
- const key = `Commander.Command.${id}.state` as const
1388
- const stateTag = ServiceMap.Service<typeof key, State>(key)
1389
-
1390
- const makeContext_ = () => this.makeContext(id, { ...options, state: state?.value })
1391
- const initialContext = makeContext_()
1392
- const context = computed(() => makeContext_())
1393
- const action = computed(() => context.value.action)
1394
- const label = computed(() => context.value.label)
1395
-
1396
- const errorReporter = <A, E, R>(self: Effect.Effect<A, E, R>) =>
1397
- self.pipe(
1398
- Effect.tapCause(
1399
- Effect.fnUntraced(function*(cause) {
1400
- if (Cause.hasInterruptsOnly(cause)) {
1401
- console.info(`Interrupted while trying to ${id}`)
1402
- return
1403
- }
1404
-
1405
- const fail = Cause.findErrorOption(cause)
1406
- if (Option.isSome(fail)) {
1407
- // if (fail.value._tag === "SuppressErrors") {
1408
- // console.info(
1409
- // `Suppressed error trying to ${action}`,
1410
- // fail.value,
1411
- // )
1412
- // return
1413
- // }
1414
- const message = `Failure trying to ${id}`
1415
- yield* reportMessage(message, {
1416
- action: id,
1417
- error: fail.value
1418
- })
1419
- return
1420
- }
1421
-
1422
- const context = yield* CommandContext
1423
- const extra = {
1424
- action: context.action,
1425
- message: `Unexpected Error trying to ${id}`
1426
- }
1427
- yield* reportRuntimeError(cause, extra)
1428
- }, Effect.uninterruptible)
1429
- )
1430
- )
1431
-
1432
- const currentState = Effect.sync(() => state.value)
1433
-
1434
- const theHandler = flow(
1435
- handler,
1436
- errorReporter,
1437
- // all must be within the Effect.fn to fit within the Span
1438
- Effect.provideServiceEffect(
1439
- stateTag,
1440
- currentState
1441
- ),
1442
- Effect.provideServiceEffect(
1443
- CommandContext,
1444
- Effect.sync(() => makeContext_())
1445
- )
1446
- )
1447
- const waitId = options?.waitKey ? options.waitKey(id) : undefined
1448
- const blockId = options?.blockKey ? options.blockKey(id) : undefined
1449
-
1450
- const [result, exec_] = asResult(theHandler)
1451
-
1452
- const exec = Effect
1453
- .fnUntraced(
1454
- function*(...args: [any, any]) {
1455
- if (waitId !== undefined) registerWait(waitId)
1456
- if (blockId !== undefined && blockId !== waitId) {
1457
- registerWait(blockId)
1458
- }
1459
- return yield* exec_(...args)
1460
- },
1461
- Effect.onExit(() =>
1462
- Effect.sync(() => {
1463
- if (waitId !== undefined) unregisterWait(waitId)
1464
- if (blockId !== undefined && blockId !== waitId) {
1465
- unregisterWait(blockId)
1466
- }
1467
- })
1468
- )
1469
- )
1470
-
1471
- const waiting = waitId !== undefined
1472
- ? computed(() => result.value.waiting || (waitState.value[waitId] ?? 0) > 0)
1473
- : computed(() => result.value.waiting)
1474
-
1475
- const blocked = blockId !== undefined
1476
- ? computed(() => waiting.value || (waitState.value[blockId] ?? 0) > 0)
1477
- : computed(() => waiting.value)
1478
-
1479
- const computeAllowed = options?.allowed
1480
- const allowed = computeAllowed ? computed(() => computeAllowed(id, state)) : true
1481
-
1482
- const rt = Effect.services<RT | RTHooks>().pipe(Effect.provide(this.hooks)).pipe(Effect.runSyncWith(this.rt))
1483
- const runFork = Effect.runForkWith(rt)
1484
-
1485
- const handle = Object.assign((arg: Arg) => {
1486
- // we capture the call site stack here
1487
- const limit = Error.stackTraceLimit
1488
- Error.stackTraceLimit = 2
1489
- const errorCall = new Error()
1490
- Error.stackTraceLimit = limit
1491
-
1492
- let cache: false | string = false
1493
- const captureStackTrace = () => {
1494
- // in case of an error, we want to append the definition stack to the call site stack,
1495
- // so we can see where the handler was defined too
1496
-
1497
- if (cache !== false) {
1498
- return cache
1499
- }
1500
- if (errorCall.stack) {
1501
- const stackDef = errorDef!.stack!.trim().split("\n")
1502
- const stackCall = errorCall.stack.trim().split("\n")
1503
- let endStackDef = stackDef.slice(2).join("\n").trim()
1504
- if (!endStackDef.includes(`(`)) {
1505
- endStackDef = endStackDef.replace(/at (.*)/, "at ($1)")
1506
- }
1507
- let endStackCall = stackCall.slice(2).join("\n").trim()
1508
- if (!endStackCall.includes(`(`)) {
1509
- endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
1510
- }
1511
- cache = `${endStackDef}\n${endStackCall}`
1512
- return cache
1513
- }
1514
- }
1515
-
1516
- const command = currentState.pipe(Effect.flatMap((state) =>
1517
- Effect.withSpan(
1518
- exec(arg, { ...context.value, state } as any),
1519
- id,
1520
- {
1521
- captureStackTrace,
1522
- attributes: {
1523
- input: arg,
1524
- state,
1525
- action: initialContext.action,
1526
- label: initialContext.label,
1527
- id: initialContext.id,
1528
- i18nKey: initialContext.i18nKey
1529
- }
1530
- }
1531
- )
1532
- ))
1533
-
1534
- return runFork(command)
1535
- }, { action, label })
1536
-
1537
- return reactive({
1538
- /** static */
1539
- id,
1540
-
1541
- /** the base i18n key, based on id by default. static */
1542
- i18nKey: initialContext.i18nKey,
1543
- /** the `action.` namespace based on i18nKey.. static */
1544
- namespace: initialContext.namespace,
1545
-
1546
- /** easy generate namespaced 18n keys, based on namespace. static */
1547
- namespaced: initialContext.namespaced,
1548
-
1549
- /** reactive */
1550
- result,
1551
- /** reactive */
1552
- waiting,
1553
- /** reactive */
1554
- blocked,
1555
- /** reactive */
1556
- allowed,
1557
- /** reactive */
1558
- action,
1559
- /** reactive */
1560
- label,
1561
- /** reactive */
1562
- state,
1563
-
1564
- handle
1565
- })
1566
- },
1567
- { id }
1568
- )
1569
- }
1570
-
1571
- // /** @experimental */
1572
- // takeOver:
1573
- // <Args extends any[], A, E, R, const Id extends string>(command: Commander.CommandOut<Args, A, E, R, Id,I18nKey>) =>
1574
- // (...args: Args) => {
1575
- // // we capture the call site stack here
1576
- // const limit = Error.stackTraceLimit
1577
- // Error.stackTraceLimit = 2
1578
- // const errorCall = new Error()
1579
- // const localErrorDef = new Error()
1580
- // Error.stackTraceLimit = limit
1581
-
1582
- // // TODO
1583
- // const errorDef = localErrorDef
1584
-
1585
- // let cache: false | string = false
1586
- // const captureStackTrace = () => {
1587
- // // in case of an error, we want to append the definition stack to the call site stack,
1588
- // // so we can see where the handler was defined too
1589
-
1590
- // if (cache !== false) {
1591
- // return cache
1592
- // }
1593
- // if (errorCall.stack) {
1594
- // const stackDef = errorDef.stack!.trim().split("\n")
1595
- // const stackCall = errorCall.stack.trim().split("\n")
1596
- // let endStackDef = stackDef.slice(2).join("\n").trim()
1597
- // if (!endStackDef.includes(`(`)) {
1598
- // endStackDef = endStackDef.replace(/at (.*)/, "at ($1)")
1599
- // }
1600
- // let endStackCall = stackCall.slice(2).join("\n").trim()
1601
- // if (!endStackCall.includes(`(`)) {
1602
- // endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
1603
- // }
1604
- // cache = `${endStackDef}\n${endStackCall}`
1605
- // return cache
1606
- // }
1607
- // }
1608
-
1609
- // return Effect.gen(function*() {
1610
- // const ctx = yield* CommandContext
1611
- // ctx.action = command.action
1612
- // return yield* command.exec(...args).pipe(
1613
- // Effect.flatten,
1614
- // Effect.withSpan(
1615
- // command.action,
1616
- // { captureStackTrace }
1617
- // )
1618
- // )
1619
- // })
1620
- // },
1621
-
1622
- /**
1623
- * Define a Command for handling user actions with built-in error reporting and state management.
1624
- *
1625
- * @param id The internal identifier for the action. Used as a tracing span and to lookup
1626
- * the user-facing name via internationalization (`action.${id}`).
1627
- * @param options Optional configuration for internationalization and state.
1628
- * @param options.i18nCustomKey Custom i18n key to use instead of `id` (e.g., for grouping similar actions)
1629
- * @param options.state Optional reactive state object (or function returning one) that is
1630
- * made available to the command effects and can be used for i18n interpolation.
1631
- * The state is captured at the start of each command execution and remains stable throughout.
1632
- * @returns A function that executes the command when called (e.g., directly in `@click` handlers).
1633
- * Built-in error reporting handles failures automatically.
1634
- *
1635
- * **Effect Context**: Effects have access to the `CommandContext` service, which provides
1636
- * the user-facing action name.
1637
- *
1638
- * **Returned Properties**:
1639
- * - `action`: User-facing action name from intl messages (useful for button labels)
1640
- * - `result`: The command result state
1641
- * - `waiting`: Boolean indicating if the command is in progress (shorthand for `result.waiting`)
1642
- * - `handle`: Function to execute the command
1643
- * - `exec`: The raw Effect that will be executed when calling `handle` (for advanced use cases)
1644
- * - `i18nKey`, `namespace`, `namespaced`: Helpers for internationalization keys
1645
- *
1646
- * **User Feedback**: Use the `withDefaultToast` helper for status notifications, or render
1647
- * the `result` inline for custom UI feedback.
1648
- */
1649
- fn = <
1650
- const Id extends string,
1651
- const State extends IntlRecord = IntlRecord,
1652
- const I18nKey extends string = Id
1653
- >(
1654
- id: Id | { id: Id },
1655
- options?: FnOptions<Id, I18nKey, State>
1656
- ): Commander.Gen<RT | RTHooks, Id, I18nKey, State> & Commander.NonGen<RT | RTHooks, Id, I18nKey, State> & {
1657
- state: ServiceMap.Service<`Commander.Command.${Id}.state`, State>
1658
- } =>
1659
- Object.assign(
1660
- (
1661
- fn: any,
1662
- ...combinators: any[]
1663
- ): any => {
1664
- // we capture the definition stack here, so we can append it to later stack traces
1665
- const limit = Error.stackTraceLimit
1666
- Error.stackTraceLimit = 2
1667
- const errorDef = new Error()
1668
- Error.stackTraceLimit = limit
1669
-
1670
- return this.makeCommand(id, options, errorDef)(
1671
- Effect.fnUntraced(
1672
- // fnUntraced only supports generators as first arg, so we convert to generator if needed
1673
- isGeneratorFunction(fn) ? fn : function*(...args) {
1674
- return yield* fn(...args)
1675
- },
1676
- ...combinators as [any]
1677
- ) as any
1678
- )
1679
- },
1680
- makeBaseInfo(typeof id === "string" ? id : id.id, options),
1681
- {
1682
- state: ServiceMap.Service<`Commander.Command.${Id}.state`, State>(
1683
- `Commander.Command.${typeof id === "string" ? id : id.id}.state`
1684
- )
1685
- }
1686
- )
1687
-
1688
- /** @experimental @deprecated */
1689
- alt2: <
1690
- const Id extends string,
1691
- MutArg,
1692
- MutA,
1693
- MutE,
1694
- MutR,
1695
- const I18nKey extends string = Id,
1696
- State extends IntlRecord | undefined = undefined
1697
- >(
1698
- id:
1699
- | Id
1700
- | { id: Id; mutate: (arg: MutArg) => Effect.Effect<MutA, MutE, MutR> }
1701
- | ((arg: MutArg) => Effect.Effect<MutA, MutE, MutR>) & { id: Id },
1702
- options?: FnOptions<Id, I18nKey, State>
1703
- ) =>
1704
- & Commander.CommandContextLocal<Id, I18nKey>
1705
- & (<A, E, R extends RT | RTHooks | CommandContext | `Commander.Command.${Id}.state`, Arg = void>(
1706
- handler: (
1707
- ctx: Effect.fn.Traced & Effect.fn.Untraced & Commander.CommandContextLocal<Id, I18nKey> & {
1708
- // todo: only if we passed in one
1709
- mutate: (arg: Arg) => Effect.Effect<MutA, MutE, MutR>
1710
- }
1711
- ) => (arg: Arg, ctx: Commander.CommandContextLocal2<Id, I18nKey, State>) => Effect.Effect<A, E, R>
1712
- ) => Commander.CommandOut<Arg, A, E, R, Id, I18nKey, State>) = (
1713
- _id,
1714
- options?
1715
- ) => {
1716
- const isObject = Predicate.isObjectKeyword(_id)
1717
- const id = isObject ? _id.id : _id
1718
- const baseInfo = makeBaseInfo(id, options)
1719
- const idCmd = this.makeCommand(id, options)
1720
- // TODO: implement proper tracing stack
1721
- return Object.assign((cb: any) =>
1722
- idCmd(cb(
1723
- Object.assign(
1724
- (fn: any, ...combinators: any[]) =>
1725
- Effect.fnUntraced(
1726
- // fnUntraced only supports generators as first arg, so we convert to generator if needed
1727
- isGeneratorFunction(fn) ? fn : function*(...args) {
1728
- return yield* fn(...args)
1729
- },
1730
- ...combinators as [any]
1731
- ),
1732
- baseInfo,
1733
- isObject
1734
- ? { mutate: "mutate" in _id ? _id.mutate : typeof _id === "function" ? _id : undefined }
1735
- : {}
1736
- )
1737
- )), baseInfo) as any
1738
- }
1739
-
1740
- /** @experimental */
1741
- alt = this.makeCommand as unknown as <
1742
- const Id extends string,
1743
- const I18nKey extends string = Id,
1744
- State extends IntlRecord | undefined = undefined
1745
- >(
1746
- id: Id,
1747
- customI18nKey?: I18nKey
1748
- ) =>
1749
- & Commander.CommandContextLocal<Id, I18nKey>
1750
- & (<A, E, R extends RT | CommandContext | `Commander.Command.${Id}.state`, Arg = void>(
1751
- handler: (arg: Arg, ctx: Commander.CommandContextLocal2<Id, I18nKey, State>) => Effect.Effect<A, E, R>
1752
- ) => Commander.CommandOut<Arg, A, E, R, Id, I18nKey, State>)
1753
-
1754
- /**
1755
- * Define a Command for handling user actions with built-in error reporting and state management.
1756
- *
1757
- * @param mutation The mutation function to take the identifier and initial handler from. Used as a tracing span and to lookup
1758
- * the user-facing name via internationalization (`action.${id}`).
1759
- * @param options Optional configuration for internationalization and state.
1760
- * @param options.i18nCustomKey Custom i18n key to use instead of `id` (e.g., for grouping similar actions)
1761
- * @param options.state Optional reactive state object (or function returning one) that is
1762
- * made available to the command effects and can be used for i18n interpolation.
1763
- * The state is captured at the start of each command execution and remains stable throughout.
1764
- * @returns A function that executes the command when called (e.g., directly in `@click` handlers).
1765
- * Built-in error reporting handles failures automatically.
1766
- *
1767
- * **Effect Context**: Effects have access to the `CommandContext` service, which provides
1768
- * the user-facing action name.
1769
- *
1770
- * **Returned Properties**:
1771
- * - `action`: User-facing action name from intl messages (useful for button labels)
1772
- * - `result`: The command result state
1773
- * - `waiting`: Boolean indicating if the command is in progress (shorthand for `result.waiting`)
1774
- * - `handle`: Function to execute the command
1775
- * - `exec`: The raw Effect that will be executed when calling `handle` (for advanced use cases)
1776
- * - `i18nKey`, `namespace`, `namespaced`: Helpers for internationalization keys
1777
- *
1778
- * **User Feedback**: Use the `withDefaultToast` helper for status notifications, or render
1779
- * the `result` inline for custom UI feedback.
1780
- */
1781
- wrap = <
1782
- const Id extends string,
1783
- Arg,
1784
- A,
1785
- E,
1786
- R,
1787
- const State extends IntlRecord = IntlRecord,
1788
- I18nKey extends string = Id
1789
- >(
1790
- mutation:
1791
- | { mutate: (arg: Arg) => Effect.Effect<A, E, R>; id: Id }
1792
- | ((arg: Arg) => Effect.Effect<A, E, R>) & { id: Id },
1793
- options?: FnOptions<Id, I18nKey, State>
1794
- ): Commander.CommanderWrap<RT | RTHooks, Id, I18nKey, State, Arg, A, E, R> =>
1795
- Object.assign(
1796
- (
1797
- ...combinators: any[]
1798
- ): any => {
1799
- // we capture the definition stack here, so we can append it to later stack traces
1800
- const limit = Error.stackTraceLimit
1801
- Error.stackTraceLimit = 2
1802
- const errorDef = new Error()
1803
- Error.stackTraceLimit = limit
1804
- const mutate = "mutate" in mutation ? mutation.mutate : mutation
1805
-
1806
- return this.makeCommand(mutation.id, options, errorDef)(
1807
- Effect.fnUntraced(
1808
- // fnUntraced only supports generators as first arg, so we convert to generator if needed
1809
- isGeneratorFunction(mutate) ? mutate : function*(arg: Arg) {
1810
- return yield* mutate(arg)
1811
- },
1812
- ...combinators as [any]
1813
- ) as any
1814
- )
1815
- },
1816
- makeBaseInfo(mutation.id, options),
1817
- {
1818
- state: ServiceMap.Service<`Commander.Command.${Id}.state`, State>(
1819
- `Commander.Command.${mutation.id}.state`
1820
- )
1821
- }
1822
- )
1823
- }
1824
-
1825
- // @effect-diagnostics-next-line missingEffectServiceDependency:off
1826
- export class Commander extends ServiceMap.Service<Commander>()("Commander", {
1827
- make: Effect.gen(function*() {
1828
- const i18n = yield* I18n
1829
- return <RT, RTHooks>(rt: ServiceMap.ServiceMap<RT>, rtHooks: Layer.Layer<RTHooks, never, RT>) =>
1830
- new CommanderImpl(rt, i18n, rtHooks)
1831
- })
1832
- }) {
1833
- static readonly DefaultWithoutDependencies = Layer.effect(this, this.make)
1834
- static readonly Default = this.DefaultWithoutDependencies
1835
- }