@effect-app/vue 2.77.2 → 2.77.3
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 +6 -0
- package/dist/experimental/commander.d.ts +89 -25
- package/dist/experimental/commander.d.ts.map +1 -1
- package/dist/experimental/commander.js +373 -380
- package/dist/experimental/makeUseCommand.d.ts +3 -8
- package/dist/experimental/makeUseCommand.d.ts.map +1 -1
- package/dist/experimental/makeUseCommand.js +3 -6
- package/dist/makeClient.d.ts +133 -130
- package/dist/makeClient.d.ts.map +1 -1
- package/dist/makeClient.js +4 -12
- package/package.json +1 -1
- package/src/experimental/commander.ts +541 -546
- package/src/experimental/makeUseCommand.ts +7 -14
- package/src/makeClient.ts +5 -12
- package/test/dist/stubs.d.ts +3 -1
- package/test/dist/stubs.d.ts.map +1 -1
|
@@ -1120,590 +1120,585 @@ export const CommanderStatic = {
|
|
|
1120
1120
|
})
|
|
1121
1121
|
}
|
|
1122
1122
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1123
|
+
const makeBaseInfo = <const Id extends string, const I18nKey extends string = Id>(
|
|
1124
|
+
id: Id,
|
|
1125
|
+
options?: Pick<FnOptionsInternal<I18nKey>, "i18nCustomKey">
|
|
1126
|
+
) => {
|
|
1127
|
+
if (!id) throw new Error("must specify an id")
|
|
1128
|
+
const i18nKey: I18nKey = options?.i18nCustomKey ?? id as unknown as I18nKey
|
|
1129
|
+
|
|
1130
|
+
const namespace = `action.${i18nKey}` as const
|
|
1131
|
+
|
|
1132
|
+
const context = {
|
|
1133
|
+
id,
|
|
1134
|
+
i18nKey,
|
|
1135
|
+
namespace,
|
|
1136
|
+
namespaced: <const K extends string>(k: K) => `${namespace}.${k}` as const
|
|
1137
|
+
}
|
|
1128
1138
|
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
options?: Pick<FnOptionsInternal<I18nKey>, "i18nCustomKey">
|
|
1132
|
-
) => {
|
|
1133
|
-
if (!id) throw new Error("must specify an id")
|
|
1134
|
-
const i18nKey: I18nKey = options?.i18nCustomKey ?? id as unknown as I18nKey
|
|
1139
|
+
return context
|
|
1140
|
+
}
|
|
1135
1141
|
|
|
1136
|
-
|
|
1142
|
+
const getStateValues = <const I18nKey extends string, State extends IntlRecord | undefined>(
|
|
1143
|
+
options?: FnOptions<I18nKey, State>
|
|
1144
|
+
): ComputedRef<State> => {
|
|
1145
|
+
const state_ = options?.state
|
|
1146
|
+
const state = !state_ ? computed(() => undefined as State) : typeof state_ === "function"
|
|
1147
|
+
? computed(state_)
|
|
1148
|
+
: state_
|
|
1149
|
+
return state
|
|
1150
|
+
}
|
|
1137
1151
|
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1152
|
+
// class preserves JSDoc throughout..
|
|
1153
|
+
export class CommanderImpl<RT> {
|
|
1154
|
+
private runFork: <A, E>(
|
|
1155
|
+
effect: Effect.Effect<A, E, RT>,
|
|
1156
|
+
options?: Runtime.RunForkOptions | undefined
|
|
1157
|
+
) => RuntimeFiber<A, E>
|
|
1144
1158
|
|
|
1145
|
-
|
|
1146
|
-
|
|
1159
|
+
constructor(private readonly rt: Runtime.Runtime<RT>, private readonly intl: I18n) {
|
|
1160
|
+
this.runFork = Runtime.runFork(this.rt)
|
|
1161
|
+
}
|
|
1147
1162
|
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
return context
|
|
1169
|
-
}
|
|
1163
|
+
readonly makeContext = <const Id extends string, const I18nKey extends string = Id>(
|
|
1164
|
+
id: Id,
|
|
1165
|
+
options?: FnOptionsInternal<I18nKey>
|
|
1166
|
+
) => {
|
|
1167
|
+
if (!id) throw new Error("must specify an id")
|
|
1168
|
+
const i18nKey: I18nKey = options?.i18nCustomKey ?? id as unknown as I18nKey
|
|
1169
|
+
|
|
1170
|
+
const namespace = `action.${i18nKey}` as const
|
|
1171
|
+
|
|
1172
|
+
// must remain stable through out single call
|
|
1173
|
+
const action = this.intl.formatMessage({
|
|
1174
|
+
id: namespace,
|
|
1175
|
+
defaultMessage: id
|
|
1176
|
+
}, options?.state)
|
|
1177
|
+
const context = CommandContext.of({
|
|
1178
|
+
...makeBaseInfo(id, options),
|
|
1179
|
+
action,
|
|
1180
|
+
state: options?.state
|
|
1181
|
+
})
|
|
1170
1182
|
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
): ComputedRef<State> => {
|
|
1174
|
-
const state_ = options?.state
|
|
1175
|
-
const state = !state_ ? computed(() => undefined as State) : typeof state_ === "function"
|
|
1176
|
-
? computed(state_)
|
|
1177
|
-
: state_
|
|
1178
|
-
return state
|
|
1179
|
-
}
|
|
1183
|
+
return context
|
|
1184
|
+
}
|
|
1180
1185
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1186
|
+
readonly makeCommand = <
|
|
1187
|
+
const Id extends string,
|
|
1188
|
+
const State extends IntlRecord | undefined,
|
|
1189
|
+
const I18nKey extends string = Id
|
|
1190
|
+
>(
|
|
1191
|
+
id_: Id | { id: Id },
|
|
1192
|
+
options?: FnOptions<I18nKey, State>,
|
|
1193
|
+
errorDef?: Error
|
|
1194
|
+
) => {
|
|
1195
|
+
const id = typeof id_ === "string" ? id_ : id_.id
|
|
1196
|
+
const state = getStateValues(options)
|
|
1197
|
+
|
|
1198
|
+
return Object.assign(
|
|
1199
|
+
<Args extends ReadonlyArray<unknown>, A, E, R extends RT | CommandContext | `Commander.Command.${Id}.state`>(
|
|
1200
|
+
handler: (...args: Args) => Effect.Effect<A, E, R>
|
|
1187
1201
|
) => {
|
|
1188
|
-
|
|
1189
|
-
const
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
const limit = Error.stackTraceLimit
|
|
1197
|
-
Error.stackTraceLimit = 2
|
|
1198
|
-
const localErrorDef = new Error()
|
|
1199
|
-
Error.stackTraceLimit = limit
|
|
1200
|
-
if (!errorDef) {
|
|
1201
|
-
errorDef = localErrorDef
|
|
1202
|
-
}
|
|
1202
|
+
// we capture the definition stack here, so we can append it to later stack traces
|
|
1203
|
+
const limit = Error.stackTraceLimit
|
|
1204
|
+
Error.stackTraceLimit = 2
|
|
1205
|
+
const localErrorDef = new Error()
|
|
1206
|
+
Error.stackTraceLimit = limit
|
|
1207
|
+
if (!errorDef) {
|
|
1208
|
+
errorDef = localErrorDef
|
|
1209
|
+
}
|
|
1203
1210
|
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
)
|
|
1245
|
-
)
|
|
1246
|
-
|
|
1247
|
-
const currentState = Effect.sync(() => state.value)
|
|
1248
|
-
|
|
1249
|
-
const theHandler = flow(
|
|
1250
|
-
handler,
|
|
1251
|
-
errorReporter,
|
|
1252
|
-
// all must be within the Effect.fn to fit within the Span
|
|
1253
|
-
Effect.provideServiceEffect(
|
|
1254
|
-
stateTag,
|
|
1255
|
-
currentState
|
|
1256
|
-
),
|
|
1257
|
-
Effect.provideServiceEffect(
|
|
1258
|
-
CommandContext,
|
|
1259
|
-
Effect.sync(() => makeContext_())
|
|
1260
|
-
)
|
|
1211
|
+
const key = `Commander.Command.${id}.state` as const
|
|
1212
|
+
const stateTag = Context.GenericTag<typeof key, State>(key)
|
|
1213
|
+
|
|
1214
|
+
const makeContext_ = () => this.makeContext(id, { ...options, state: state?.value })
|
|
1215
|
+
const initialContext = makeContext_()
|
|
1216
|
+
const action = computed(() => makeContext_().action)
|
|
1217
|
+
|
|
1218
|
+
const errorReporter = <A, E, R>(self: Effect.Effect<A, E, R>) =>
|
|
1219
|
+
self.pipe(
|
|
1220
|
+
Effect.tapErrorCause(
|
|
1221
|
+
Effect.fnUntraced(function*(cause) {
|
|
1222
|
+
if (Cause.isInterruptedOnly(cause)) {
|
|
1223
|
+
console.info(`Interrupted while trying to ${id}`)
|
|
1224
|
+
return
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
const fail = Cause.failureOption(cause)
|
|
1228
|
+
if (Option.isSome(fail)) {
|
|
1229
|
+
// if (fail.value._tag === "SuppressErrors") {
|
|
1230
|
+
// console.info(
|
|
1231
|
+
// `Suppressed error trying to ${action}`,
|
|
1232
|
+
// fail.value,
|
|
1233
|
+
// )
|
|
1234
|
+
// return
|
|
1235
|
+
// }
|
|
1236
|
+
const message = `Failure trying to ${id}`
|
|
1237
|
+
yield* reportMessage(message, {
|
|
1238
|
+
action: id,
|
|
1239
|
+
error: fail.value
|
|
1240
|
+
})
|
|
1241
|
+
return
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
const context = yield* CommandContext
|
|
1245
|
+
const extra = {
|
|
1246
|
+
action: context.action,
|
|
1247
|
+
message: `Unexpected Error trying to ${id}`
|
|
1248
|
+
}
|
|
1249
|
+
yield* reportRuntimeError(cause, extra)
|
|
1250
|
+
}, Effect.uninterruptible)
|
|
1261
1251
|
)
|
|
1252
|
+
)
|
|
1262
1253
|
|
|
1263
|
-
|
|
1254
|
+
const currentState = Effect.sync(() => state.value)
|
|
1255
|
+
|
|
1256
|
+
const theHandler = flow(
|
|
1257
|
+
handler,
|
|
1258
|
+
errorReporter,
|
|
1259
|
+
// all must be within the Effect.fn to fit within the Span
|
|
1260
|
+
Effect.provideServiceEffect(
|
|
1261
|
+
stateTag,
|
|
1262
|
+
currentState
|
|
1263
|
+
),
|
|
1264
|
+
Effect.provideServiceEffect(
|
|
1265
|
+
CommandContext,
|
|
1266
|
+
Effect.sync(() => makeContext_())
|
|
1267
|
+
)
|
|
1268
|
+
)
|
|
1264
1269
|
|
|
1265
|
-
|
|
1270
|
+
const [result, exec] = asResult(theHandler)
|
|
1266
1271
|
|
|
1267
|
-
|
|
1268
|
-
// we capture the call site stack here
|
|
1269
|
-
const limit = Error.stackTraceLimit
|
|
1270
|
-
Error.stackTraceLimit = 2
|
|
1271
|
-
const errorCall = new Error()
|
|
1272
|
-
Error.stackTraceLimit = limit
|
|
1272
|
+
const waiting = computed(() => result.value.waiting)
|
|
1273
1273
|
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1274
|
+
const handle = Object.assign((...args: Args) => {
|
|
1275
|
+
// we capture the call site stack here
|
|
1276
|
+
const limit = Error.stackTraceLimit
|
|
1277
|
+
Error.stackTraceLimit = 2
|
|
1278
|
+
const errorCall = new Error()
|
|
1279
|
+
Error.stackTraceLimit = limit
|
|
1278
1280
|
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
cache = `${endStackDef}\n${endStackCall}`
|
|
1294
|
-
return cache
|
|
1295
|
-
}
|
|
1281
|
+
let cache: false | string = false
|
|
1282
|
+
const captureStackTrace = () => {
|
|
1283
|
+
// in case of an error, we want to append the definition stack to the call site stack,
|
|
1284
|
+
// so we can see where the handler was defined too
|
|
1285
|
+
|
|
1286
|
+
if (cache !== false) {
|
|
1287
|
+
return cache
|
|
1288
|
+
}
|
|
1289
|
+
if (errorCall.stack) {
|
|
1290
|
+
const stackDef = errorDef!.stack!.trim().split("\n")
|
|
1291
|
+
const stackCall = errorCall.stack.trim().split("\n")
|
|
1292
|
+
let endStackDef = stackDef.slice(2).join("\n").trim()
|
|
1293
|
+
if (!endStackDef.includes(`(`)) {
|
|
1294
|
+
endStackDef = endStackDef.replace(/at (.*)/, "at ($1)")
|
|
1296
1295
|
}
|
|
1296
|
+
let endStackCall = stackCall.slice(2).join("\n").trim()
|
|
1297
|
+
if (!endStackCall.includes(`(`)) {
|
|
1298
|
+
endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
|
|
1299
|
+
}
|
|
1300
|
+
cache = `${endStackDef}\n${endStackCall}`
|
|
1301
|
+
return cache
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1297
1304
|
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
)
|
|
1313
|
-
))
|
|
1314
|
-
|
|
1315
|
-
return runFork(command)
|
|
1316
|
-
}, { action })
|
|
1317
|
-
|
|
1318
|
-
const handleEffect = Object.assign((...args: Args) => {
|
|
1319
|
-
// we capture the call site stack here
|
|
1320
|
-
const limit = Error.stackTraceLimit
|
|
1321
|
-
Error.stackTraceLimit = 2
|
|
1322
|
-
const errorCall = new Error()
|
|
1323
|
-
Error.stackTraceLimit = limit
|
|
1324
|
-
|
|
1325
|
-
let cache: false | string = false
|
|
1326
|
-
const captureStackTrace = () => {
|
|
1327
|
-
// in case of an error, we want to append the definition stack to the call site stack,
|
|
1328
|
-
// so we can see where the handler was defined too
|
|
1329
|
-
|
|
1330
|
-
if (cache !== false) {
|
|
1331
|
-
return cache
|
|
1332
|
-
}
|
|
1333
|
-
if (errorCall.stack) {
|
|
1334
|
-
const stackDef = errorDef!.stack!.trim().split("\n")
|
|
1335
|
-
const stackCall = errorCall.stack.trim().split("\n")
|
|
1336
|
-
let endStackDef = stackDef.slice(2).join("\n").trim()
|
|
1337
|
-
if (!endStackDef.includes(`(`)) {
|
|
1338
|
-
endStackDef = endStackDef.replace(/at (.*)/, "at ($1)")
|
|
1339
|
-
}
|
|
1340
|
-
let endStackCall = stackCall.slice(2).join("\n").trim()
|
|
1341
|
-
if (!endStackCall.includes(`(`)) {
|
|
1342
|
-
endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
|
|
1343
|
-
}
|
|
1344
|
-
cache = `${endStackDef}\n${endStackCall}`
|
|
1345
|
-
return cache
|
|
1305
|
+
const command = currentState.pipe(Effect.flatMap((state) =>
|
|
1306
|
+
Effect.withSpan(
|
|
1307
|
+
exec(...args),
|
|
1308
|
+
id,
|
|
1309
|
+
{
|
|
1310
|
+
captureStackTrace,
|
|
1311
|
+
attributes: {
|
|
1312
|
+
input: args,
|
|
1313
|
+
state,
|
|
1314
|
+
action: initialContext.action,
|
|
1315
|
+
id: initialContext.id,
|
|
1316
|
+
i18nKey: initialContext.i18nKey
|
|
1346
1317
|
}
|
|
1347
1318
|
}
|
|
1319
|
+
)
|
|
1320
|
+
))
|
|
1348
1321
|
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
let
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
}
|
|
1378
|
-
if (errorCall.stack) {
|
|
1379
|
-
const stackDef = errorDef!.stack!.trim().split("\n")
|
|
1380
|
-
const stackCall = errorCall.stack.trim().split("\n")
|
|
1381
|
-
let endStackDef = stackDef.slice(2).join("\n").trim()
|
|
1382
|
-
if (!endStackDef.includes(`(`)) {
|
|
1383
|
-
endStackDef = endStackDef.replace(/at (.*)/, "at ($1)")
|
|
1384
|
-
}
|
|
1385
|
-
let endStackCall = stackCall.slice(2).join("\n").trim()
|
|
1386
|
-
if (!endStackCall.includes(`(`)) {
|
|
1387
|
-
endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
|
|
1388
|
-
}
|
|
1389
|
-
cache = `${endStackDef}\n${endStackCall}`
|
|
1390
|
-
return cache
|
|
1391
|
-
}
|
|
1322
|
+
return this.runFork(command)
|
|
1323
|
+
}, { action })
|
|
1324
|
+
|
|
1325
|
+
const handleEffect = Object.assign((...args: Args) => {
|
|
1326
|
+
// we capture the call site stack here
|
|
1327
|
+
const limit = Error.stackTraceLimit
|
|
1328
|
+
Error.stackTraceLimit = 2
|
|
1329
|
+
const errorCall = new Error()
|
|
1330
|
+
Error.stackTraceLimit = limit
|
|
1331
|
+
|
|
1332
|
+
let cache: false | string = false
|
|
1333
|
+
const captureStackTrace = () => {
|
|
1334
|
+
// in case of an error, we want to append the definition stack to the call site stack,
|
|
1335
|
+
// so we can see where the handler was defined too
|
|
1336
|
+
|
|
1337
|
+
if (cache !== false) {
|
|
1338
|
+
return cache
|
|
1339
|
+
}
|
|
1340
|
+
if (errorCall.stack) {
|
|
1341
|
+
const stackDef = errorDef!.stack!.trim().split("\n")
|
|
1342
|
+
const stackCall = errorCall.stack.trim().split("\n")
|
|
1343
|
+
let endStackDef = stackDef.slice(2).join("\n").trim()
|
|
1344
|
+
if (!endStackDef.includes(`(`)) {
|
|
1345
|
+
endStackDef = endStackDef.replace(/at (.*)/, "at ($1)")
|
|
1346
|
+
}
|
|
1347
|
+
let endStackCall = stackCall.slice(2).join("\n").trim()
|
|
1348
|
+
if (!endStackCall.includes(`(`)) {
|
|
1349
|
+
endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
|
|
1392
1350
|
}
|
|
1351
|
+
cache = `${endStackDef}\n${endStackCall}`
|
|
1352
|
+
return cache
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1393
1355
|
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
cache = `${endStackDef}\n${endStackCall}`
|
|
1430
|
-
return cache
|
|
1431
|
-
}
|
|
1356
|
+
const command = Effect.withSpan(
|
|
1357
|
+
exec(...args),
|
|
1358
|
+
id,
|
|
1359
|
+
{ captureStackTrace }
|
|
1360
|
+
)
|
|
1361
|
+
|
|
1362
|
+
return Effect.currentSpan.pipe(
|
|
1363
|
+
Effect.option,
|
|
1364
|
+
Effect.map((span) =>
|
|
1365
|
+
this.runFork(Option.isSome(span) ? command.pipe(Effect.withParentSpan(span.value)) : command)
|
|
1366
|
+
)
|
|
1367
|
+
)
|
|
1368
|
+
}, { action, state })
|
|
1369
|
+
|
|
1370
|
+
const compose = Object.assign((...args: Args) => {
|
|
1371
|
+
// we capture the call site stack here
|
|
1372
|
+
const limit = Error.stackTraceLimit
|
|
1373
|
+
Error.stackTraceLimit = 2
|
|
1374
|
+
const errorCall = new Error()
|
|
1375
|
+
Error.stackTraceLimit = limit
|
|
1376
|
+
|
|
1377
|
+
let cache: false | string = false
|
|
1378
|
+
const captureStackTrace = () => {
|
|
1379
|
+
// in case of an error, we want to append the definition stack to the call site stack,
|
|
1380
|
+
// so we can see where the handler was defined too
|
|
1381
|
+
|
|
1382
|
+
if (cache !== false) {
|
|
1383
|
+
return cache
|
|
1384
|
+
}
|
|
1385
|
+
if (errorCall.stack) {
|
|
1386
|
+
const stackDef = errorDef!.stack!.trim().split("\n")
|
|
1387
|
+
const stackCall = errorCall.stack.trim().split("\n")
|
|
1388
|
+
let endStackDef = stackDef.slice(2).join("\n").trim()
|
|
1389
|
+
if (!endStackDef.includes(`(`)) {
|
|
1390
|
+
endStackDef = endStackDef.replace(/at (.*)/, "at ($1)")
|
|
1432
1391
|
}
|
|
1392
|
+
let endStackCall = stackCall.slice(2).join("\n").trim()
|
|
1393
|
+
if (!endStackCall.includes(`(`)) {
|
|
1394
|
+
endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
|
|
1395
|
+
}
|
|
1396
|
+
cache = `${endStackDef}\n${endStackCall}`
|
|
1397
|
+
return cache
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1433
1400
|
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1401
|
+
const command = Effect.withSpan(
|
|
1402
|
+
exec(...args),
|
|
1403
|
+
id,
|
|
1404
|
+
{ captureStackTrace }
|
|
1405
|
+
)
|
|
1439
1406
|
|
|
1440
|
-
|
|
1441
|
-
|
|
1407
|
+
return command
|
|
1408
|
+
}, { action })
|
|
1442
1409
|
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1410
|
+
const compose2 = Object.assign((...args: Args) => {
|
|
1411
|
+
// we capture the call site stack here
|
|
1412
|
+
const limit = Error.stackTraceLimit
|
|
1413
|
+
Error.stackTraceLimit = 2
|
|
1414
|
+
const errorCall = new Error()
|
|
1415
|
+
Error.stackTraceLimit = limit
|
|
1446
1416
|
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
/** easy generate namespaced 18n keys, based on namespace. static */
|
|
1453
|
-
namespaced: initialContext.namespaced,
|
|
1454
|
-
|
|
1455
|
-
/** reactive */
|
|
1456
|
-
result,
|
|
1457
|
-
/** reactive */
|
|
1458
|
-
waiting,
|
|
1459
|
-
/** reactive */
|
|
1460
|
-
action,
|
|
1461
|
-
|
|
1462
|
-
handle,
|
|
1463
|
-
|
|
1464
|
-
/** experimental */
|
|
1465
|
-
handleEffect,
|
|
1466
|
-
/** experimental */
|
|
1467
|
-
compose,
|
|
1468
|
-
/** experimental */
|
|
1469
|
-
compose2,
|
|
1470
|
-
/** experimental */
|
|
1471
|
-
exec
|
|
1472
|
-
})
|
|
1473
|
-
},
|
|
1474
|
-
{ id }
|
|
1475
|
-
)
|
|
1476
|
-
}
|
|
1477
|
-
}
|
|
1417
|
+
let cache: false | string = false
|
|
1418
|
+
const captureStackTrace = () => {
|
|
1419
|
+
// in case of an error, we want to append the definition stack to the call site stack,
|
|
1420
|
+
// so we can see where the handler was defined too
|
|
1478
1421
|
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
// takeOver:
|
|
1482
|
-
// <Args extends any[], A, E, R, const Id extends string>(command: Commander.CommandOut<Args, A, E, R, Id,I18nKey>) =>
|
|
1483
|
-
// (...args: Args) => {
|
|
1484
|
-
// // we capture the call site stack here
|
|
1485
|
-
// const limit = Error.stackTraceLimit
|
|
1486
|
-
// Error.stackTraceLimit = 2
|
|
1487
|
-
// const errorCall = new Error()
|
|
1488
|
-
// const localErrorDef = new Error()
|
|
1489
|
-
// Error.stackTraceLimit = limit
|
|
1490
|
-
|
|
1491
|
-
// // TODO
|
|
1492
|
-
// const errorDef = localErrorDef
|
|
1493
|
-
|
|
1494
|
-
// let cache: false | string = false
|
|
1495
|
-
// const captureStackTrace = () => {
|
|
1496
|
-
// // in case of an error, we want to append the definition stack to the call site stack,
|
|
1497
|
-
// // so we can see where the handler was defined too
|
|
1498
|
-
|
|
1499
|
-
// if (cache !== false) {
|
|
1500
|
-
// return cache
|
|
1501
|
-
// }
|
|
1502
|
-
// if (errorCall.stack) {
|
|
1503
|
-
// const stackDef = errorDef.stack!.trim().split("\n")
|
|
1504
|
-
// const stackCall = errorCall.stack.trim().split("\n")
|
|
1505
|
-
// let endStackDef = stackDef.slice(2).join("\n").trim()
|
|
1506
|
-
// if (!endStackDef.includes(`(`)) {
|
|
1507
|
-
// endStackDef = endStackDef.replace(/at (.*)/, "at ($1)")
|
|
1508
|
-
// }
|
|
1509
|
-
// let endStackCall = stackCall.slice(2).join("\n").trim()
|
|
1510
|
-
// if (!endStackCall.includes(`(`)) {
|
|
1511
|
-
// endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
|
|
1512
|
-
// }
|
|
1513
|
-
// cache = `${endStackDef}\n${endStackCall}`
|
|
1514
|
-
// return cache
|
|
1515
|
-
// }
|
|
1516
|
-
// }
|
|
1517
|
-
|
|
1518
|
-
// return Effect.gen(function*() {
|
|
1519
|
-
// const ctx = yield* CommandContext
|
|
1520
|
-
// ctx.action = command.action
|
|
1521
|
-
// return yield* command.exec(...args).pipe(
|
|
1522
|
-
// Effect.flatten,
|
|
1523
|
-
// Effect.withSpan(
|
|
1524
|
-
// command.action,
|
|
1525
|
-
// { captureStackTrace }
|
|
1526
|
-
// )
|
|
1527
|
-
// )
|
|
1528
|
-
// })
|
|
1529
|
-
// },
|
|
1530
|
-
|
|
1531
|
-
fn: <RT>(runtime: Runtime.Runtime<RT>) => {
|
|
1532
|
-
const make = makeCommand(runtime)
|
|
1533
|
-
/**
|
|
1534
|
-
* Define a Command for handling user actions with built-in error reporting and state management.
|
|
1535
|
-
*
|
|
1536
|
-
* @param id The internal identifier for the action. Used as a tracing span and to lookup
|
|
1537
|
-
* the user-facing name via internationalization (`action.${id}`).
|
|
1538
|
-
* @returns A function that executes the command when called (e.g., directly in `@click` handlers).
|
|
1539
|
-
* Built-in error reporting handles failures automatically.
|
|
1540
|
-
*
|
|
1541
|
-
* **Effect Context**: Effects have access to the `CommandContext` service, which provides
|
|
1542
|
-
* the user-facing action name.
|
|
1543
|
-
*
|
|
1544
|
-
* **Returned Properties**:
|
|
1545
|
-
* - `action`: User-facing action name from intl messages (useful for button labels)
|
|
1546
|
-
* - `result`: The command result state
|
|
1547
|
-
* - `waiting`: Boolean indicating if the command is in progress (shorthand for `result.waiting`)
|
|
1548
|
-
* - `handle`: Function to execute the command
|
|
1549
|
-
*
|
|
1550
|
-
* **User Feedback**: Use the `withDefaultToast` helper for status notifications, or render
|
|
1551
|
-
* the `result` inline for custom UI feedback.
|
|
1552
|
-
*/
|
|
1553
|
-
const f = <
|
|
1554
|
-
const Id extends string,
|
|
1555
|
-
const State extends IntlRecord = IntlRecord,
|
|
1556
|
-
const I18nKey extends string = Id
|
|
1557
|
-
>(
|
|
1558
|
-
id: Id | { id: Id },
|
|
1559
|
-
options?: FnOptions<I18nKey, State>
|
|
1560
|
-
): Commander.Gen<RT, Id, I18nKey> & Commander.NonGen<RT, Id, I18nKey> & {
|
|
1561
|
-
state: Context.Tag<`Commander.Command.${Id}.state`, State>
|
|
1562
|
-
} =>
|
|
1563
|
-
Object.assign(
|
|
1564
|
-
(
|
|
1565
|
-
fn: any,
|
|
1566
|
-
...combinators: any[]
|
|
1567
|
-
): any => {
|
|
1568
|
-
// we capture the definition stack here, so we can append it to later stack traces
|
|
1569
|
-
const limit = Error.stackTraceLimit
|
|
1570
|
-
Error.stackTraceLimit = 2
|
|
1571
|
-
const errorDef = new Error()
|
|
1572
|
-
Error.stackTraceLimit = limit
|
|
1573
|
-
|
|
1574
|
-
return make(id, options, errorDef)(
|
|
1575
|
-
Effect.fnUntraced(
|
|
1576
|
-
// fnUntraced only supports generators as first arg, so we convert to generator if needed
|
|
1577
|
-
isGeneratorFunction(fn) ? fn : function*(...args) {
|
|
1578
|
-
return yield* fn(...args)
|
|
1579
|
-
},
|
|
1580
|
-
...combinators as [any]
|
|
1581
|
-
) as any
|
|
1582
|
-
)
|
|
1583
|
-
},
|
|
1584
|
-
makeBaseInfo(typeof id === "string" ? id : id.id, options),
|
|
1585
|
-
{
|
|
1586
|
-
state: Context.GenericTag<`Commander.Command.${Id}.state`, State>(
|
|
1587
|
-
`Commander.Command.${typeof id === "string" ? id : id.id}.state`
|
|
1588
|
-
)
|
|
1422
|
+
if (cache !== false) {
|
|
1423
|
+
return cache
|
|
1589
1424
|
}
|
|
1425
|
+
if (errorCall.stack) {
|
|
1426
|
+
const stackDef = errorDef!.stack!.trim().split("\n")
|
|
1427
|
+
const stackCall = errorCall.stack.trim().split("\n")
|
|
1428
|
+
let endStackDef = stackDef.slice(2).join("\n").trim()
|
|
1429
|
+
if (!endStackDef.includes(`(`)) {
|
|
1430
|
+
endStackDef = endStackDef.replace(/at (.*)/, "at ($1)")
|
|
1431
|
+
}
|
|
1432
|
+
let endStackCall = stackCall.slice(2).join("\n").trim()
|
|
1433
|
+
if (!endStackCall.includes(`(`)) {
|
|
1434
|
+
endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
|
|
1435
|
+
}
|
|
1436
|
+
cache = `${endStackDef}\n${endStackCall}`
|
|
1437
|
+
return cache
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
const command = Effect.withSpan(
|
|
1442
|
+
exec(...args).pipe(Effect.flatten),
|
|
1443
|
+
id,
|
|
1444
|
+
{ captureStackTrace }
|
|
1590
1445
|
)
|
|
1591
|
-
|
|
1446
|
+
|
|
1447
|
+
return command
|
|
1448
|
+
}, { action })
|
|
1449
|
+
|
|
1450
|
+
return reactive({
|
|
1451
|
+
/** static */
|
|
1452
|
+
id,
|
|
1453
|
+
|
|
1454
|
+
/** the base i18n key, based on id by default. static */
|
|
1455
|
+
i18nKey: initialContext.i18nKey,
|
|
1456
|
+
/** the `action.` namespace based on i18nKey.. static */
|
|
1457
|
+
namespace: initialContext.namespace,
|
|
1458
|
+
|
|
1459
|
+
/** easy generate namespaced 18n keys, based on namespace. static */
|
|
1460
|
+
namespaced: initialContext.namespaced,
|
|
1461
|
+
|
|
1462
|
+
/** reactive */
|
|
1463
|
+
result,
|
|
1464
|
+
/** reactive */
|
|
1465
|
+
waiting,
|
|
1466
|
+
/** reactive */
|
|
1467
|
+
action,
|
|
1468
|
+
|
|
1469
|
+
handle,
|
|
1470
|
+
|
|
1471
|
+
/** experimental */
|
|
1472
|
+
handleEffect,
|
|
1473
|
+
/** experimental */
|
|
1474
|
+
compose,
|
|
1475
|
+
/** experimental */
|
|
1476
|
+
compose2,
|
|
1477
|
+
/** experimental */
|
|
1478
|
+
exec
|
|
1479
|
+
})
|
|
1592
1480
|
},
|
|
1481
|
+
{ id }
|
|
1482
|
+
)
|
|
1483
|
+
}
|
|
1593
1484
|
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1485
|
+
// /** @experimental */
|
|
1486
|
+
// takeOver:
|
|
1487
|
+
// <Args extends any[], A, E, R, const Id extends string>(command: Commander.CommandOut<Args, A, E, R, Id,I18nKey>) =>
|
|
1488
|
+
// (...args: Args) => {
|
|
1489
|
+
// // we capture the call site stack here
|
|
1490
|
+
// const limit = Error.stackTraceLimit
|
|
1491
|
+
// Error.stackTraceLimit = 2
|
|
1492
|
+
// const errorCall = new Error()
|
|
1493
|
+
// const localErrorDef = new Error()
|
|
1494
|
+
// Error.stackTraceLimit = limit
|
|
1495
|
+
|
|
1496
|
+
// // TODO
|
|
1497
|
+
// const errorDef = localErrorDef
|
|
1498
|
+
|
|
1499
|
+
// let cache: false | string = false
|
|
1500
|
+
// const captureStackTrace = () => {
|
|
1501
|
+
// // in case of an error, we want to append the definition stack to the call site stack,
|
|
1502
|
+
// // so we can see where the handler was defined too
|
|
1503
|
+
|
|
1504
|
+
// if (cache !== false) {
|
|
1505
|
+
// return cache
|
|
1506
|
+
// }
|
|
1507
|
+
// if (errorCall.stack) {
|
|
1508
|
+
// const stackDef = errorDef.stack!.trim().split("\n")
|
|
1509
|
+
// const stackCall = errorCall.stack.trim().split("\n")
|
|
1510
|
+
// let endStackDef = stackDef.slice(2).join("\n").trim()
|
|
1511
|
+
// if (!endStackDef.includes(`(`)) {
|
|
1512
|
+
// endStackDef = endStackDef.replace(/at (.*)/, "at ($1)")
|
|
1513
|
+
// }
|
|
1514
|
+
// let endStackCall = stackCall.slice(2).join("\n").trim()
|
|
1515
|
+
// if (!endStackCall.includes(`(`)) {
|
|
1516
|
+
// endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
|
|
1517
|
+
// }
|
|
1518
|
+
// cache = `${endStackDef}\n${endStackCall}`
|
|
1519
|
+
// return cache
|
|
1520
|
+
// }
|
|
1521
|
+
// }
|
|
1522
|
+
|
|
1523
|
+
// return Effect.gen(function*() {
|
|
1524
|
+
// const ctx = yield* CommandContext
|
|
1525
|
+
// ctx.action = command.action
|
|
1526
|
+
// return yield* command.exec(...args).pipe(
|
|
1527
|
+
// Effect.flatten,
|
|
1528
|
+
// Effect.withSpan(
|
|
1529
|
+
// command.action,
|
|
1530
|
+
// { captureStackTrace }
|
|
1531
|
+
// )
|
|
1532
|
+
// )
|
|
1533
|
+
// })
|
|
1534
|
+
// },
|
|
1535
|
+
|
|
1536
|
+
/**
|
|
1537
|
+
* Define a Command for handling user actions with built-in error reporting and state management.
|
|
1538
|
+
*
|
|
1539
|
+
* @param id The internal identifier for the action. Used as a tracing span and to lookup
|
|
1540
|
+
* the user-facing name via internationalization (`action.${id}`).
|
|
1541
|
+
* @returns A function that executes the command when called (e.g., directly in `@click` handlers).
|
|
1542
|
+
* Built-in error reporting handles failures automatically.
|
|
1543
|
+
*
|
|
1544
|
+
* **Effect Context**: Effects have access to the `CommandContext` service, which provides
|
|
1545
|
+
* the user-facing action name.
|
|
1546
|
+
*
|
|
1547
|
+
* **Returned Properties**:
|
|
1548
|
+
* - `action`: User-facing action name from intl messages (useful for button labels)
|
|
1549
|
+
* - `result`: The command result state
|
|
1550
|
+
* - `waiting`: Boolean indicating if the command is in progress (shorthand for `result.waiting`)
|
|
1551
|
+
* - `handle`: Function to execute the command
|
|
1552
|
+
*
|
|
1553
|
+
* **User Feedback**: Use the `withDefaultToast` helper for status notifications, or render
|
|
1554
|
+
* the `result` inline for custom UI feedback.
|
|
1555
|
+
*/
|
|
1556
|
+
fn = <
|
|
1557
|
+
const Id extends string,
|
|
1558
|
+
const State extends IntlRecord = IntlRecord,
|
|
1559
|
+
const I18nKey extends string = Id
|
|
1560
|
+
>(
|
|
1561
|
+
id: Id | { id: Id },
|
|
1562
|
+
options?: FnOptions<I18nKey, State>
|
|
1563
|
+
): Commander.Gen<RT, Id, I18nKey> & Commander.NonGen<RT, Id, I18nKey> & {
|
|
1564
|
+
state: Context.Tag<`Commander.Command.${Id}.state`, State>
|
|
1565
|
+
} =>
|
|
1566
|
+
Object.assign(
|
|
1567
|
+
(
|
|
1568
|
+
fn: any,
|
|
1569
|
+
...combinators: any[]
|
|
1570
|
+
): any => {
|
|
1571
|
+
// we capture the definition stack here, so we can append it to later stack traces
|
|
1572
|
+
const limit = Error.stackTraceLimit
|
|
1573
|
+
Error.stackTraceLimit = 2
|
|
1574
|
+
const errorDef = new Error()
|
|
1575
|
+
Error.stackTraceLimit = limit
|
|
1576
|
+
|
|
1577
|
+
return this.makeCommand(id, options, errorDef)(
|
|
1578
|
+
Effect.fnUntraced(
|
|
1579
|
+
// fnUntraced only supports generators as first arg, so we convert to generator if needed
|
|
1580
|
+
isGeneratorFunction(fn) ? fn : function*(...args) {
|
|
1581
|
+
return yield* fn(...args)
|
|
1582
|
+
},
|
|
1583
|
+
...combinators as [any]
|
|
1584
|
+
) as any
|
|
1585
|
+
)
|
|
1648
1586
|
},
|
|
1587
|
+
makeBaseInfo(typeof id === "string" ? id : id.id, options),
|
|
1588
|
+
{
|
|
1589
|
+
state: Context.GenericTag<`Commander.Command.${Id}.state`, State>(
|
|
1590
|
+
`Commander.Command.${typeof id === "string" ? id : id.id}.state`
|
|
1591
|
+
)
|
|
1592
|
+
}
|
|
1593
|
+
)
|
|
1649
1594
|
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
Object.assign(
|
|
1685
|
-
...combinators: any[]
|
|
1686
|
-
): any => {
|
|
1687
|
-
// we capture the definition stack here, so we can append it to later stack traces
|
|
1688
|
-
const limit = Error.stackTraceLimit
|
|
1689
|
-
Error.stackTraceLimit = 2
|
|
1690
|
-
const errorDef = new Error()
|
|
1691
|
-
Error.stackTraceLimit = limit
|
|
1692
|
-
|
|
1693
|
-
const mutate = "mutate" in mutation ? mutation.mutate : mutation
|
|
1694
|
-
|
|
1695
|
-
return make(mutation.id, options, errorDef)(
|
|
1595
|
+
/** @experimental */
|
|
1596
|
+
alt2: <
|
|
1597
|
+
const Id extends string,
|
|
1598
|
+
MutArgs extends Array<unknown>,
|
|
1599
|
+
MutA,
|
|
1600
|
+
MutE,
|
|
1601
|
+
MutR,
|
|
1602
|
+
const I18nKey extends string = Id
|
|
1603
|
+
>(
|
|
1604
|
+
id:
|
|
1605
|
+
| Id
|
|
1606
|
+
| { id: Id; mutate: (...args: MutArgs) => Effect.Effect<MutA, MutE, MutR> }
|
|
1607
|
+
| ((...args: MutArgs) => Effect.Effect<MutA, MutE, MutR>) & { id: Id },
|
|
1608
|
+
options?: FnOptions<I18nKey, IntlRecord>
|
|
1609
|
+
) =>
|
|
1610
|
+
& Commander.CommandContextLocal<Id, I18nKey>
|
|
1611
|
+
& (<Args extends Array<unknown>, A, E, R extends RT | CommandContext | `Commander.Command.${Id}.state`>(
|
|
1612
|
+
handler: (
|
|
1613
|
+
ctx: Effect.fn.Gen & Effect.fn.NonGen & Commander.CommandContextLocal<Id, I18nKey> & {
|
|
1614
|
+
// todo: only if we passed in one
|
|
1615
|
+
mutate: (...args: MutArgs) => Effect.Effect<MutA, MutE, MutR>
|
|
1616
|
+
}
|
|
1617
|
+
) => (...args: Args) => Effect.Effect<A, E, R>
|
|
1618
|
+
) => Commander.CommandOut<Args, A, E, R, Id, I18nKey>) = (
|
|
1619
|
+
_id,
|
|
1620
|
+
options?
|
|
1621
|
+
) => {
|
|
1622
|
+
const isObject = typeof _id === "object" || typeof _id === "function"
|
|
1623
|
+
const id = isObject ? _id.id : _id
|
|
1624
|
+
const baseInfo = makeBaseInfo(id, options)
|
|
1625
|
+
const idCmd = this.makeCommand(id, options)
|
|
1626
|
+
// TODO: implement proper tracing stack
|
|
1627
|
+
return Object.assign((cb: any) =>
|
|
1628
|
+
idCmd(cb(
|
|
1629
|
+
Object.assign(
|
|
1630
|
+
(fn: any, ...combinators: any[]) =>
|
|
1696
1631
|
Effect.fnUntraced(
|
|
1697
1632
|
// fnUntraced only supports generators as first arg, so we convert to generator if needed
|
|
1698
|
-
isGeneratorFunction(
|
|
1699
|
-
return yield*
|
|
1633
|
+
isGeneratorFunction(fn) ? fn : function*(...args) {
|
|
1634
|
+
return yield* fn(...args)
|
|
1700
1635
|
},
|
|
1701
1636
|
...combinators as [any]
|
|
1702
|
-
)
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1637
|
+
),
|
|
1638
|
+
baseInfo,
|
|
1639
|
+
isObject
|
|
1640
|
+
? { mutate: "mutate" in _id ? _id.mutate : typeof _id === "function" ? _id : undefined }
|
|
1641
|
+
: {}
|
|
1642
|
+
)
|
|
1643
|
+
)), baseInfo) as any
|
|
1707
1644
|
}
|
|
1645
|
+
|
|
1646
|
+
/** @experimental */
|
|
1647
|
+
alt = this.makeCommand as unknown as <const Id extends string, const I18nKey extends string = Id>(
|
|
1648
|
+
id: Id,
|
|
1649
|
+
customI18nKey?: I18nKey
|
|
1650
|
+
) =>
|
|
1651
|
+
& Commander.CommandContextLocal<Id, I18nKey>
|
|
1652
|
+
& (<Args extends Array<unknown>, A, E, R extends RT | CommandContext | `Commander.Command.${Id}.state`>(
|
|
1653
|
+
handler: (...args: Args) => Effect.Effect<A, E, R>
|
|
1654
|
+
) => Commander.CommandOut<Args, A, E, R, Id, I18nKey>)
|
|
1655
|
+
|
|
1656
|
+
/** @experimental */
|
|
1657
|
+
wrap = <
|
|
1658
|
+
const Id extends string,
|
|
1659
|
+
Args extends Array<unknown>,
|
|
1660
|
+
A,
|
|
1661
|
+
E,
|
|
1662
|
+
R,
|
|
1663
|
+
const State extends IntlRecord = IntlRecord,
|
|
1664
|
+
I18nKey extends string = Id
|
|
1665
|
+
>(
|
|
1666
|
+
mutation:
|
|
1667
|
+
| { mutate: (...args: Args) => Effect.Effect<A, E, R>; id: Id }
|
|
1668
|
+
| ((...args: Args) => Effect.Effect<A, E, R>) & { id: Id },
|
|
1669
|
+
options?: FnOptions<I18nKey, State>
|
|
1670
|
+
):
|
|
1671
|
+
& Commander.CommandContextLocal<Id, I18nKey>
|
|
1672
|
+
& Commander.GenWrap<RT, Id, I18nKey, Args, A, E, R>
|
|
1673
|
+
& Commander.NonGenWrap<RT, Id, I18nKey, Args, A, E, R> =>
|
|
1674
|
+
Object.assign((
|
|
1675
|
+
...combinators: any[]
|
|
1676
|
+
): any => {
|
|
1677
|
+
// we capture the definition stack here, so we can append it to later stack traces
|
|
1678
|
+
const limit = Error.stackTraceLimit
|
|
1679
|
+
Error.stackTraceLimit = 2
|
|
1680
|
+
const errorDef = new Error()
|
|
1681
|
+
Error.stackTraceLimit = limit
|
|
1682
|
+
|
|
1683
|
+
const mutate = "mutate" in mutation ? mutation.mutate : mutation
|
|
1684
|
+
|
|
1685
|
+
return this.makeCommand(mutation.id, options, errorDef)(
|
|
1686
|
+
Effect.fnUntraced(
|
|
1687
|
+
// fnUntraced only supports generators as first arg, so we convert to generator if needed
|
|
1688
|
+
isGeneratorFunction(mutate) ? mutate : function*(...args: Args) {
|
|
1689
|
+
return yield* mutate(...args)
|
|
1690
|
+
},
|
|
1691
|
+
...combinators as [any]
|
|
1692
|
+
) as any
|
|
1693
|
+
)
|
|
1694
|
+
}, makeBaseInfo(mutation.id, options))
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
// @effect-diagnostics-next-line missingEffectServiceDependency:off
|
|
1698
|
+
export class Commander extends Effect.Service<Commander>()("Commander", {
|
|
1699
|
+
dependencies: [WithToast.Default, Confirm.Default],
|
|
1700
|
+
effect: Effect.gen(function*() {
|
|
1701
|
+
const i18n = yield* I18n
|
|
1702
|
+
return <RT>(rt: Runtime.Runtime<RT>) => new CommanderImpl(rt, i18n)
|
|
1708
1703
|
})
|
|
1709
1704
|
}) {}
|