@effect-app/vue 4.0.0-beta.187 → 4.0.0-beta.188
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.
- package/CHANGELOG.md +13 -0
- package/dist/commander.d.ts +23 -82
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +31 -108
- package/dist/makeClient.d.ts +5 -59
- package/dist/makeClient.d.ts.map +1 -1
- package/dist/makeClient.js +4 -59
- package/dist/makeUseCommand.d.ts +1 -1
- package/dist/mutate.d.ts +5 -11
- package/dist/mutate.d.ts.map +1 -1
- package/dist/mutate.js +5 -53
- package/examples/streamMutation.ts +4 -23
- package/package.json +2 -2
- package/src/commander.ts +147 -221
- package/src/makeClient.ts +6 -167
- package/src/makeUseCommand.ts +1 -1
- package/src/mutate.ts +4 -80
- package/test/Mutation.test.ts +0 -26
- package/test/dist/stubs.d.ts +2 -151
- package/test/dist/stubs.d.ts.map +1 -1
- package/test/makeClient.test.ts +2 -24
- package/test/streamFinal.test.ts +2 -49
- package/test/streamFn.test.ts +219 -1
package/src/commander.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { asResult, asStreamResult, deepToRaw, type MissingDependencies, reportRu
|
|
|
3
3
|
import { reportMessage } from "@effect-app/vue/errorReporter"
|
|
4
4
|
import { Cause, Context, Effect, type Exit, type Fiber, flow, Layer, Match, MutableHashMap, Option, Predicate, S } from "effect-app"
|
|
5
5
|
import { SupportedErrors } from "effect-app/client"
|
|
6
|
-
import { OperationFailure, OperationSuccess } from "effect-app/Operations"
|
|
7
6
|
import { isGeneratorFunction, wrapEffect } from "effect-app/utils"
|
|
8
7
|
import { type Refinement } from "effect/Predicate"
|
|
9
8
|
import * as Stream from "effect/Stream"
|
|
@@ -23,41 +22,6 @@ type IntlRecord = Record<string, PrimitiveType | FormatXMLElementFn<string, stri
|
|
|
23
22
|
*/
|
|
24
23
|
export type Progress = string | { readonly text: string; readonly percentage: number }
|
|
25
24
|
|
|
26
|
-
/**
|
|
27
|
-
* Options accepted when calling a stream mutation factory.
|
|
28
|
-
* Supplying `progress` causes the resulting command to expose `running`
|
|
29
|
-
* (the live AsyncResult ref) and `progress` (formatted loading info).
|
|
30
|
-
* When omitted, neither is exposed on the command.
|
|
31
|
-
*/
|
|
32
|
-
export type StreamMutationCallOptions<A, E> = {
|
|
33
|
-
progress?: (result: AsyncResult.AsyncResult<A, E>) => Progress | undefined
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* The result of invoking a `mutateToResult` factory: the `execute` function (or
|
|
38
|
-
* `Effect`, when the request takes no input) carries `id`, plus `running` and
|
|
39
|
-
* `progress` when the factory was called with a `progress` formatter. Pass
|
|
40
|
-
* directly to `Command.fn` / `Command.wrap` / `Command.wrapStream`, or invoke
|
|
41
|
-
* to run the stream.
|
|
42
|
-
*/
|
|
43
|
-
type StreamMutationCallable<Id extends string, Arg, A, E, R> =
|
|
44
|
-
& (((arg: Arg) => Effect.Effect<any, E, R>) | Effect.Effect<any, E, R>)
|
|
45
|
-
& {
|
|
46
|
-
readonly id: Id
|
|
47
|
-
readonly _streamCallable: true
|
|
48
|
-
readonly running?: ComputedRef<AsyncResult.AsyncResult<A, E>>
|
|
49
|
-
readonly progress?: ComputedRef<Progress | undefined>
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
type StreamMutationFactory<Id extends string, Arg, A, E, R> =
|
|
53
|
-
& ((options?: StreamMutationCallOptions<A, E>) => StreamMutationCallable<Id, Arg, A, E, R>)
|
|
54
|
-
& { readonly id: Id; readonly _streamFactory: true }
|
|
55
|
-
|
|
56
|
-
const isStreamFactory = (x: unknown): x is StreamMutationFactory<string, any, any, any, any> =>
|
|
57
|
-
typeof x === "function" && (x as any)._streamFactory === true
|
|
58
|
-
|
|
59
|
-
const isStreamCallable = (x: unknown): x is StreamMutationCallable<string, any, any, any, any> =>
|
|
60
|
-
x !== null && x !== undefined && (x as any)._streamCallable === true
|
|
61
25
|
type FnOptions<
|
|
62
26
|
Id extends string,
|
|
63
27
|
I18nCustomKey extends string,
|
|
@@ -218,15 +182,8 @@ export declare namespace Commander {
|
|
|
218
182
|
/** reactive */
|
|
219
183
|
result: AsyncResult.AsyncResult<A, E>
|
|
220
184
|
/**
|
|
221
|
-
* reactive –
|
|
222
|
-
*
|
|
223
|
-
* Reflects the live AsyncResult of the underlying stream.
|
|
224
|
-
*/
|
|
225
|
-
running: AsyncResult.AsyncResult<any, any> | undefined
|
|
226
|
-
/**
|
|
227
|
-
* reactive – formatted progress info computed from `running` via the
|
|
228
|
-
* `progress` option. Useful as the loading state on a `CommandButton`.
|
|
229
|
-
* Undefined when no `progress` formatter was supplied.
|
|
185
|
+
* reactive – formatted progress info driven by `Command.mapProgress` or `Command.updateProgress`
|
|
186
|
+
* inside a `streamFn` handler. Undefined for non-stream commands.
|
|
230
187
|
*/
|
|
231
188
|
progress: Progress | undefined
|
|
232
189
|
/** reactive */
|
|
@@ -1873,6 +1830,97 @@ export declare namespace Commander {
|
|
|
1873
1830
|
? CommandOut<Arg, SA2, SE2 | EE2, SR2 | ER2, Id, I18nKey, State>
|
|
1874
1831
|
: never
|
|
1875
1832
|
}
|
|
1833
|
+
|
|
1834
|
+
/**
|
|
1835
|
+
* Type returned by `mutate.wrap` on a stream handler — analogous to `CommanderWrap` but for streams.
|
|
1836
|
+
* The handler is pre-baked (from the stream mutation), so this is called with only optional combinators.
|
|
1837
|
+
*/
|
|
1838
|
+
export type StreamerWrap<
|
|
1839
|
+
RT,
|
|
1840
|
+
Id extends string,
|
|
1841
|
+
I18nKey extends string,
|
|
1842
|
+
State extends IntlRecord | undefined,
|
|
1843
|
+
Arg,
|
|
1844
|
+
SA,
|
|
1845
|
+
SE,
|
|
1846
|
+
SR
|
|
1847
|
+
> =
|
|
1848
|
+
& CommandContextLocal<Id, I18nKey>
|
|
1849
|
+
& { readonly state: Context.Service<`Commander.Command.${Id}.state`, State> }
|
|
1850
|
+
& {
|
|
1851
|
+
(): Exclude<SR, RT> extends never ? CommandOut<Arg, SA, SE, SR, Id, I18nKey, State>
|
|
1852
|
+
: MissingDependencies<RT, SR> & {}
|
|
1853
|
+
<A extends Stream.Stream<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>>(
|
|
1854
|
+
a: (
|
|
1855
|
+
_: Stream.Stream<SA, SE, SR>,
|
|
1856
|
+
arg: ArgForCombinator<Arg>,
|
|
1857
|
+
ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
|
|
1858
|
+
) => A
|
|
1859
|
+
): CommandOut<Arg, Stream.Success<A>, Stream.Error<A>, Stream.Services<A>, Id, I18nKey, State>
|
|
1860
|
+
<
|
|
1861
|
+
B,
|
|
1862
|
+
A extends Stream.Stream<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>
|
|
1863
|
+
>(
|
|
1864
|
+
a: (
|
|
1865
|
+
_: Stream.Stream<SA, SE, SR>,
|
|
1866
|
+
arg: ArgForCombinator<Arg>,
|
|
1867
|
+
ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
|
|
1868
|
+
) => B,
|
|
1869
|
+
b: (
|
|
1870
|
+
_: B,
|
|
1871
|
+
arg: ArgForCombinator<Arg>,
|
|
1872
|
+
ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
|
|
1873
|
+
) => A
|
|
1874
|
+
): CommandOut<Arg, Stream.Success<A>, Stream.Error<A>, Stream.Services<A>, Id, I18nKey, State>
|
|
1875
|
+
<
|
|
1876
|
+
B,
|
|
1877
|
+
C,
|
|
1878
|
+
A extends Stream.Stream<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>
|
|
1879
|
+
>(
|
|
1880
|
+
a: (
|
|
1881
|
+
_: Stream.Stream<SA, SE, SR>,
|
|
1882
|
+
arg: ArgForCombinator<Arg>,
|
|
1883
|
+
ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
|
|
1884
|
+
) => B,
|
|
1885
|
+
b: (
|
|
1886
|
+
_: B,
|
|
1887
|
+
arg: ArgForCombinator<Arg>,
|
|
1888
|
+
ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
|
|
1889
|
+
) => C,
|
|
1890
|
+
c: (
|
|
1891
|
+
_: C,
|
|
1892
|
+
arg: ArgForCombinator<Arg>,
|
|
1893
|
+
ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
|
|
1894
|
+
) => A
|
|
1895
|
+
): CommandOut<Arg, Stream.Success<A>, Stream.Error<A>, Stream.Services<A>, Id, I18nKey, State>
|
|
1896
|
+
<
|
|
1897
|
+
B,
|
|
1898
|
+
C,
|
|
1899
|
+
D,
|
|
1900
|
+
A extends Stream.Stream<any, any, RT | CommandContext | `Commander.Command.${Id}.state`>
|
|
1901
|
+
>(
|
|
1902
|
+
a: (
|
|
1903
|
+
_: Stream.Stream<SA, SE, SR>,
|
|
1904
|
+
arg: ArgForCombinator<Arg>,
|
|
1905
|
+
ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
|
|
1906
|
+
) => B,
|
|
1907
|
+
b: (
|
|
1908
|
+
_: B,
|
|
1909
|
+
arg: ArgForCombinator<Arg>,
|
|
1910
|
+
ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
|
|
1911
|
+
) => C,
|
|
1912
|
+
c: (
|
|
1913
|
+
_: C,
|
|
1914
|
+
arg: ArgForCombinator<Arg>,
|
|
1915
|
+
ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
|
|
1916
|
+
) => D,
|
|
1917
|
+
d: (
|
|
1918
|
+
_: D,
|
|
1919
|
+
arg: ArgForCombinator<Arg>,
|
|
1920
|
+
ctx: CommandContextLocal2<NoInfer<Id>, NoInfer<I18nKey>, NoInfer<State>>
|
|
1921
|
+
) => A
|
|
1922
|
+
): CommandOut<Arg, Stream.Success<A>, Stream.Error<A>, Stream.Services<A>, Id, I18nKey, State>
|
|
1923
|
+
}
|
|
1876
1924
|
}
|
|
1877
1925
|
|
|
1878
1926
|
type ErrorRenderer<E, Args extends readonly any[]> = (e: E, action: string, ...args: Args) => string | undefined
|
|
@@ -1966,25 +2014,15 @@ const defaultFailureMessageHandler = <E, Args extends Array<unknown>, AME, AMR>(
|
|
|
1966
2014
|
),
|
|
1967
2015
|
onSome: (e) => {
|
|
1968
2016
|
const rendered = renderError(action, errorRenderer)(e, ...args)
|
|
1969
|
-
return
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
}
|
|
1979
|
-
: {
|
|
1980
|
-
level: "warn" as const,
|
|
1981
|
-
message: `${
|
|
1982
|
-
intl.formatMessage(
|
|
1983
|
-
{ id: "handle.with_errors" },
|
|
1984
|
-
{ action }
|
|
1985
|
-
)
|
|
1986
|
-
}:\n` + rendered
|
|
1987
|
-
}
|
|
2017
|
+
return {
|
|
2018
|
+
level: "warn" as const,
|
|
2019
|
+
message: `${
|
|
2020
|
+
intl.formatMessage(
|
|
2021
|
+
{ id: "handle.with_errors" },
|
|
2022
|
+
{ action }
|
|
2023
|
+
)
|
|
2024
|
+
}:\n` + rendered
|
|
2025
|
+
}
|
|
1988
2026
|
}
|
|
1989
2027
|
})
|
|
1990
2028
|
})
|
|
@@ -2180,14 +2218,13 @@ export const CommanderStatic = {
|
|
|
2180
2218
|
),
|
|
2181
2219
|
onSuccess: options?.onSuccess === null
|
|
2182
2220
|
? null
|
|
2183
|
-
: (
|
|
2221
|
+
: (_a, ..._args) =>
|
|
2184
2222
|
hasCustomSuccess
|
|
2185
2223
|
? intl.formatMessage(
|
|
2186
2224
|
{ id: customSuccess },
|
|
2187
2225
|
cc.state
|
|
2188
2226
|
)
|
|
2189
|
-
:
|
|
2190
|
-
+ (S.is(OperationSuccess)(a) && a.message ? "\n" + a.message : "")),
|
|
2227
|
+
: intl.formatMessage({ id: "handle.success" }, { action: cc.action }),
|
|
2191
2228
|
onFailure: defaultFailureMessageHandler(
|
|
2192
2229
|
hasCustomFailure ? intl.formatMessage({ id: customFailure }, cc.state) : cc.action,
|
|
2193
2230
|
options?.errorRenderer as ErrorRenderer<E, Args> | undefined
|
|
@@ -2362,7 +2399,6 @@ export const CommanderStatic = {
|
|
|
2362
2399
|
: hasCustomSuccess
|
|
2363
2400
|
? intl.formatMessage({ id: customSuccess }, cc.state)
|
|
2364
2401
|
: intl.formatMessage({ id: "handle.success" }, { action: cc.action })
|
|
2365
|
-
+ (S.is(OperationSuccess)(lastValue) && lastValue.message ? "\n" + lastValue.message : "")
|
|
2366
2402
|
|
|
2367
2403
|
if (successMsg === null) return Effect.void
|
|
2368
2404
|
|
|
@@ -2495,17 +2531,11 @@ export class CommanderImpl<RT, RTHooks> {
|
|
|
2495
2531
|
readonly makeCommand = <
|
|
2496
2532
|
const Id extends string,
|
|
2497
2533
|
const State extends IntlRecord | undefined,
|
|
2498
|
-
const I18nKey extends string = Id
|
|
2499
|
-
RunningA = unknown,
|
|
2500
|
-
RunningE = unknown
|
|
2534
|
+
const I18nKey extends string = Id
|
|
2501
2535
|
>(
|
|
2502
2536
|
id_: Id | { id: Id },
|
|
2503
2537
|
options?: FnOptions<Id, I18nKey, State>,
|
|
2504
|
-
errorDef?: Error
|
|
2505
|
-
streamMeta?: {
|
|
2506
|
-
running?: ComputedRef<AsyncResult.AsyncResult<RunningA, RunningE>> | undefined
|
|
2507
|
-
progress?: ComputedRef<Progress | undefined> | undefined
|
|
2508
|
-
}
|
|
2538
|
+
errorDef?: Error
|
|
2509
2539
|
) => {
|
|
2510
2540
|
const id = typeof id_ === "string" ? id_ : id_.id
|
|
2511
2541
|
const state = getStateValues(options)
|
|
@@ -2690,12 +2720,8 @@ export class CommanderImpl<RT, RTHooks> {
|
|
|
2690
2720
|
|
|
2691
2721
|
/** reactive */
|
|
2692
2722
|
result,
|
|
2693
|
-
/**
|
|
2694
|
-
|
|
2695
|
-
running: streamMeta?.running,
|
|
2696
|
-
/** reactive – formatted progress info for current `running` state, when `progress`
|
|
2697
|
-
* formatter was supplied to the stream factory */
|
|
2698
|
-
progress: streamMeta?.progress,
|
|
2723
|
+
/** always undefined for non-stream commands */
|
|
2724
|
+
progress: undefined,
|
|
2699
2725
|
/** reactive */
|
|
2700
2726
|
waiting,
|
|
2701
2727
|
/** reactive */
|
|
@@ -2797,40 +2823,14 @@ export class CommanderImpl<RT, RTHooks> {
|
|
|
2797
2823
|
fn = <
|
|
2798
2824
|
const Id extends string,
|
|
2799
2825
|
const State extends IntlRecord = IntlRecord,
|
|
2800
|
-
const I18nKey extends string = Id
|
|
2801
|
-
RunningA = unknown,
|
|
2802
|
-
RunningE = unknown
|
|
2826
|
+
const I18nKey extends string = Id
|
|
2803
2827
|
>(
|
|
2804
|
-
id:
|
|
2805
|
-
| Id
|
|
2806
|
-
| { id: Id }
|
|
2807
|
-
| StreamMutationCallable<Id, any, RunningA, RunningE, any>
|
|
2808
|
-
| StreamMutationFactory<Id, any, RunningA, RunningE, any>,
|
|
2828
|
+
id: Id | { id: Id },
|
|
2809
2829
|
options?: FnOptions<Id, I18nKey, State>
|
|
2810
2830
|
): Commander.Gen<RT | RTHooks, Id, I18nKey, State> & Commander.NonGen<RT | RTHooks, Id, I18nKey, State> & {
|
|
2811
2831
|
state: Context.Service<`Commander.Command.${Id}.state`, State>
|
|
2812
2832
|
} => {
|
|
2813
|
-
|
|
2814
|
-
const resolvedId: Id = typeof id === "string" ? id : (id as { id: Id }).id
|
|
2815
|
-
const factory = isStreamFactory(id)
|
|
2816
|
-
const callable = !factory && isStreamCallable(id)
|
|
2817
|
-
const resolveStreamMeta = ():
|
|
2818
|
-
| {
|
|
2819
|
-
running?: ComputedRef<AsyncResult.AsyncResult<RunningA, RunningE>> | undefined
|
|
2820
|
-
progress?: ComputedRef<Progress | undefined> | undefined
|
|
2821
|
-
}
|
|
2822
|
-
| undefined =>
|
|
2823
|
-
{
|
|
2824
|
-
if (factory) {
|
|
2825
|
-
const c = id()
|
|
2826
|
-
return { running: c.running, progress: c.progress }
|
|
2827
|
-
}
|
|
2828
|
-
if (callable) {
|
|
2829
|
-
const c = id as StreamMutationCallable<Id, any, RunningA, RunningE, any>
|
|
2830
|
-
return { running: c.running, progress: c.progress }
|
|
2831
|
-
}
|
|
2832
|
-
return undefined
|
|
2833
|
-
}
|
|
2833
|
+
const resolvedId: Id = typeof id === "string" ? id : id.id
|
|
2834
2834
|
return Object.assign(
|
|
2835
2835
|
(
|
|
2836
2836
|
fn: any,
|
|
@@ -2842,9 +2842,7 @@ export class CommanderImpl<RT, RTHooks> {
|
|
|
2842
2842
|
const errorDef = new Error()
|
|
2843
2843
|
Error.stackTraceLimit = limit
|
|
2844
2844
|
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
return this.makeCommand(resolvedId, options, errorDef, streamMeta)(
|
|
2845
|
+
return this.makeCommand(resolvedId, options, errorDef)(
|
|
2848
2846
|
Effect.fnUntraced(
|
|
2849
2847
|
// fnUntraced only supports generators as first arg, so we convert to generator if needed
|
|
2850
2848
|
isGeneratorFunction(fn) ? fn : function*(...args) {
|
|
@@ -3047,8 +3045,6 @@ export class CommanderImpl<RT, RTHooks> {
|
|
|
3047
3045
|
namespace: initialContext.namespace,
|
|
3048
3046
|
namespaced: initialContext.namespaced,
|
|
3049
3047
|
result,
|
|
3050
|
-
/** always undefined for streamFn commands — `result` already exposes the live stream state */
|
|
3051
|
-
running: undefined,
|
|
3052
3048
|
/** reactive – progress driven by `Command.mapProgress` or `Command.updateProgress` inside the stream */
|
|
3053
3049
|
progress,
|
|
3054
3050
|
waiting,
|
|
@@ -3270,147 +3266,77 @@ export class CommanderImpl<RT, RTHooks> {
|
|
|
3270
3266
|
* **User Feedback**: Use the `withDefaultToast` helper for status notifications, or render
|
|
3271
3267
|
* the `result` inline for custom UI feedback.
|
|
3272
3268
|
*/
|
|
3273
|
-
|
|
3269
|
+
streamWrap = <
|
|
3274
3270
|
const Id extends string,
|
|
3275
3271
|
Arg,
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3272
|
+
SA,
|
|
3273
|
+
SE,
|
|
3274
|
+
SR,
|
|
3279
3275
|
const State extends IntlRecord = IntlRecord,
|
|
3280
3276
|
I18nKey extends string = Id
|
|
3281
3277
|
>(
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
| ((arg: Arg) => Effect.Effect<A, E, R>) & { id: Id }
|
|
3285
|
-
| StreamMutationFactory<Id, Arg, A, E, R>
|
|
3286
|
-
| {
|
|
3287
|
-
id: Id
|
|
3288
|
-
mutateToResult:
|
|
3289
|
-
| StreamMutationFactory<Id, Arg, A, E, R>
|
|
3290
|
-
| StreamMutationCallable<Id, Arg, A, E, R>
|
|
3291
|
-
}
|
|
3292
|
-
| StreamMutationCallable<Id, Arg, A, E, R>,
|
|
3278
|
+
handler: (arg: Arg, ctx: Commander.CommandContextLocal2<Id, I18nKey, State>) => Stream.Stream<SA, SE, SR>,
|
|
3279
|
+
id: Id,
|
|
3293
3280
|
options?: FnOptions<Id, I18nKey, State>
|
|
3294
|
-
): Commander.
|
|
3295
|
-
if (mutation !== null && typeof mutation === "object" && "mutateToResult" in mutation) {
|
|
3296
|
-
return this.wrapStream(mutation as any, options) as any
|
|
3297
|
-
}
|
|
3298
|
-
if (isStreamCallable(mutation) || isStreamFactory(mutation)) {
|
|
3299
|
-
return this.wrapStream(mutation as any, options) as any
|
|
3300
|
-
}
|
|
3301
|
-
// At this point mutation is either { mutate, id } or (fn & { id })
|
|
3302
|
-
const callMutation = mutation as
|
|
3303
|
-
| { mutate: (arg: Arg) => Effect.Effect<A, E, R>; id: Id }
|
|
3304
|
-
| (((arg: Arg) => Effect.Effect<A, E, R>) & { id: Id })
|
|
3281
|
+
): Commander.StreamerWrap<RT | RTHooks, Id, I18nKey, State, Arg, SA, SE, SR> => {
|
|
3305
3282
|
return Object.assign(
|
|
3306
|
-
(
|
|
3307
|
-
...combinators: any[]
|
|
3308
|
-
): any => {
|
|
3309
|
-
// we capture the definition stack here, so we can append it to later stack traces
|
|
3283
|
+
(...combinators: any[]): any => {
|
|
3310
3284
|
const limit = Error.stackTraceLimit
|
|
3311
3285
|
Error.stackTraceLimit = 2
|
|
3312
3286
|
const errorDef = new Error()
|
|
3313
3287
|
Error.stackTraceLimit = limit
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
return
|
|
3323
|
-
}
|
|
3324
|
-
...combinators as [any]
|
|
3325
|
-
) as any
|
|
3288
|
+
return this.makeStreamCommand(id, options, errorDef)(
|
|
3289
|
+
combinators.length === 0
|
|
3290
|
+
? handler
|
|
3291
|
+
: (arg: Arg, ctx: Commander.CommandContextLocal2<Id, I18nKey, State>) => {
|
|
3292
|
+
let current: any = handler(arg, ctx)
|
|
3293
|
+
for (const combinator of combinators) {
|
|
3294
|
+
current = combinator(current, arg, ctx)
|
|
3295
|
+
}
|
|
3296
|
+
return current
|
|
3297
|
+
}
|
|
3326
3298
|
)
|
|
3327
3299
|
},
|
|
3328
|
-
makeBaseInfo(
|
|
3300
|
+
makeBaseInfo(id, options),
|
|
3329
3301
|
{
|
|
3330
3302
|
state: Context.Service<`Commander.Command.${Id}.state`, State>(
|
|
3331
|
-
`Commander.Command.${
|
|
3303
|
+
`Commander.Command.${id}.state`
|
|
3332
3304
|
)
|
|
3333
3305
|
}
|
|
3334
3306
|
)
|
|
3335
3307
|
}
|
|
3336
3308
|
|
|
3337
|
-
|
|
3338
|
-
* Define a Command from a stream-type mutation (`mutateToResult` factory).
|
|
3339
|
-
* The stream's reactive `AsyncResult` ref is exposed as `running` for independent progress tracking.
|
|
3340
|
-
* The command's own `result` reflects the execution outcome of the `execute` function.
|
|
3341
|
-
* Supports the same combinator pipeline as `wrap` (e.g. `withDefaultToast`).
|
|
3342
|
-
*
|
|
3343
|
-
* Each invocation of the resulting wrap call produces a fresh `[ref, execute]` pair
|
|
3344
|
-
* (the `mutateToResult` factory is called once per build), so independent commands
|
|
3345
|
-
* don't share progress state.
|
|
3346
|
-
*
|
|
3347
|
-
* Accepts either:
|
|
3348
|
-
* - An object with `id` and `mutateToResult` factory (e.g. a client entry)
|
|
3349
|
-
* - The `mutateToResult` factory directly (callable, with `id`)
|
|
3350
|
-
* - An already-called factory result (`[resultRef, execute] & { id }`) — shared ref across builds
|
|
3351
|
-
*
|
|
3352
|
-
* @example
|
|
3353
|
-
* ```ts
|
|
3354
|
-
* // Via client entry (recommended):
|
|
3355
|
-
* const exportCmd = Command.wrapStream(client.myExport)()
|
|
3356
|
-
*
|
|
3357
|
-
* // Via factory directly:
|
|
3358
|
-
* const exportCmd = Command.wrapStream(client.myExport.mutateToResult)()
|
|
3359
|
-
*
|
|
3360
|
-
* // Via already-called factory (shared ref):
|
|
3361
|
-
* const stream = client.myExport.mutateToResult()
|
|
3362
|
-
* const exportCmd = Command.wrapStream(stream)()
|
|
3363
|
-
* ```
|
|
3364
|
-
*/
|
|
3365
|
-
wrapStream = <
|
|
3309
|
+
wrap = <
|
|
3366
3310
|
const Id extends string,
|
|
3367
3311
|
Arg,
|
|
3368
3312
|
A,
|
|
3369
3313
|
E,
|
|
3370
3314
|
R,
|
|
3371
3315
|
const State extends IntlRecord = IntlRecord,
|
|
3372
|
-
|
|
3316
|
+
I18nKey extends string = Id
|
|
3373
3317
|
>(
|
|
3374
3318
|
mutation:
|
|
3375
|
-
| {
|
|
3376
|
-
|
|
3377
|
-
mutateToResult:
|
|
3378
|
-
| StreamMutationFactory<Id, Arg, A, E, R>
|
|
3379
|
-
| StreamMutationCallable<Id, Arg, A, E, R>
|
|
3380
|
-
}
|
|
3381
|
-
| StreamMutationFactory<Id, Arg, A, E, R>
|
|
3382
|
-
| StreamMutationCallable<Id, Arg, A, E, R>,
|
|
3319
|
+
| { mutate: (arg: Arg) => Effect.Effect<A, E, R>; id: Id }
|
|
3320
|
+
| ((arg: Arg) => Effect.Effect<A, E, R>) & { id: Id },
|
|
3383
3321
|
options?: FnOptions<Id, I18nKey, State>
|
|
3384
3322
|
): Commander.CommanderWrap<RT | RTHooks, Id, I18nKey, State, Arg, A, E, R> => {
|
|
3385
|
-
const
|
|
3386
|
-
// Resolve `source` to the factory or already-invoked callable.
|
|
3387
|
-
const source: StreamMutationFactory<Id, Arg, A, E, R> | StreamMutationCallable<Id, Arg, A, E, R> =
|
|
3388
|
-
mutation !== null && typeof mutation === "object" && "mutateToResult" in mutation
|
|
3389
|
-
? (mutation.mutateToResult as any)
|
|
3390
|
-
: (mutation as any)
|
|
3391
|
-
const resolveCallable = (): StreamMutationCallable<Id, Arg, A, E, R> =>
|
|
3392
|
-
(isStreamFactory(source)
|
|
3393
|
-
? (source as StreamMutationFactory<Id, Arg, A, E, R>)()
|
|
3394
|
-
: source) as StreamMutationCallable<Id, Arg, A, E, R>
|
|
3323
|
+
const callMutation = mutation
|
|
3395
3324
|
return Object.assign(
|
|
3396
|
-
(
|
|
3325
|
+
(
|
|
3326
|
+
...combinators: any[]
|
|
3327
|
+
): any => {
|
|
3397
3328
|
// we capture the definition stack here, so we can append it to later stack traces
|
|
3398
3329
|
const limit = Error.stackTraceLimit
|
|
3399
3330
|
Error.stackTraceLimit = 2
|
|
3400
3331
|
const errorDef = new Error()
|
|
3401
3332
|
Error.stackTraceLimit = limit
|
|
3333
|
+
const mutate = "mutate" in callMutation
|
|
3334
|
+
? callMutation.mutate
|
|
3335
|
+
: callMutation
|
|
3402
3336
|
|
|
3403
|
-
|
|
3404
|
-
// wrap call gets its own state + execute pair. `running`/`progress`
|
|
3405
|
-
// are only surfaced when the factory was called with a `progress` formatter.
|
|
3406
|
-
const callable = resolveCallable()
|
|
3407
|
-
const mutate: (_arg: Arg) => Effect.Effect<any, E, R> = Effect.isEffect(callable)
|
|
3408
|
-
? (_arg: Arg) => callable
|
|
3409
|
-
: callable as (arg: Arg) => Effect.Effect<any, E, R>
|
|
3410
|
-
const streamMeta = { running: callable.running, progress: callable.progress }
|
|
3411
|
-
|
|
3412
|
-
return this.makeCommand(id, options, errorDef, streamMeta)(
|
|
3337
|
+
return this.makeCommand(callMutation.id, options, errorDef)(
|
|
3413
3338
|
Effect.fnUntraced(
|
|
3339
|
+
// fnUntraced only supports generators as first arg, so we convert to generator if needed
|
|
3414
3340
|
isGeneratorFunction(mutate) ? mutate : function*(arg: Arg) {
|
|
3415
3341
|
return yield* mutate(arg)
|
|
3416
3342
|
},
|
|
@@ -3418,10 +3344,10 @@ export class CommanderImpl<RT, RTHooks> {
|
|
|
3418
3344
|
) as any
|
|
3419
3345
|
)
|
|
3420
3346
|
},
|
|
3421
|
-
makeBaseInfo(id, options),
|
|
3347
|
+
makeBaseInfo(callMutation.id, options),
|
|
3422
3348
|
{
|
|
3423
3349
|
state: Context.Service<`Commander.Command.${Id}.state`, State>(
|
|
3424
|
-
`Commander.Command.${id}.state`
|
|
3350
|
+
`Commander.Command.${callMutation.id}.state`
|
|
3425
3351
|
)
|
|
3426
3352
|
}
|
|
3427
3353
|
)
|