@effect-app/vue 2.77.1 → 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 +12 -0
- package/dist/experimental/commander.d.ts +89 -44
- package/dist/experimental/commander.d.ts.map +1 -1
- package/dist/experimental/commander.js +373 -362
- 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 +151 -134
- package/dist/makeClient.d.ts.map +1 -1
- package/dist/makeClient.js +4 -12
- package/package.json +1 -1
- package/src/experimental/commander.ts +543 -522
- 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,564 +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
|
-
|
|
1294
|
-
|
|
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)")
|
|
1295
|
+
}
|
|
1296
|
+
let endStackCall = stackCall.slice(2).join("\n").trim()
|
|
1297
|
+
if (!endStackCall.includes(`(`)) {
|
|
1298
|
+
endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
|
|
1296
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
|
-
// so we can see where the handler was defined too
|
|
1374
|
-
|
|
1375
|
-
if (cache !== false) {
|
|
1376
|
-
return cache
|
|
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)")
|
|
1392
1346
|
}
|
|
1347
|
+
let endStackCall = stackCall.slice(2).join("\n").trim()
|
|
1348
|
+
if (!endStackCall.includes(`(`)) {
|
|
1349
|
+
endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
|
|
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
|
-
|
|
1430
|
-
|
|
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)")
|
|
1391
|
+
}
|
|
1392
|
+
let endStackCall = stackCall.slice(2).join("\n").trim()
|
|
1393
|
+
if (!endStackCall.includes(`(`)) {
|
|
1394
|
+
endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
|
|
1432
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
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
action,
|
|
1450
|
-
handle,
|
|
1451
|
-
handleEffect,
|
|
1452
|
-
compose,
|
|
1453
|
-
compose2,
|
|
1454
|
-
exec
|
|
1455
|
-
})
|
|
1456
|
-
},
|
|
1457
|
-
{ id }
|
|
1458
|
-
)
|
|
1459
|
-
}
|
|
1460
|
-
}
|
|
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
|
|
1461
1416
|
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
// return cache
|
|
1484
|
-
// }
|
|
1485
|
-
// if (errorCall.stack) {
|
|
1486
|
-
// const stackDef = errorDef.stack!.trim().split("\n")
|
|
1487
|
-
// const stackCall = errorCall.stack.trim().split("\n")
|
|
1488
|
-
// let endStackDef = stackDef.slice(2).join("\n").trim()
|
|
1489
|
-
// if (!endStackDef.includes(`(`)) {
|
|
1490
|
-
// endStackDef = endStackDef.replace(/at (.*)/, "at ($1)")
|
|
1491
|
-
// }
|
|
1492
|
-
// let endStackCall = stackCall.slice(2).join("\n").trim()
|
|
1493
|
-
// if (!endStackCall.includes(`(`)) {
|
|
1494
|
-
// endStackCall = endStackCall.replace(/at (.*)/, "at ($1)")
|
|
1495
|
-
// }
|
|
1496
|
-
// cache = `${endStackDef}\n${endStackCall}`
|
|
1497
|
-
// return cache
|
|
1498
|
-
// }
|
|
1499
|
-
// }
|
|
1500
|
-
|
|
1501
|
-
// return Effect.gen(function*() {
|
|
1502
|
-
// const ctx = yield* CommandContext
|
|
1503
|
-
// ctx.action = command.action
|
|
1504
|
-
// return yield* command.exec(...args).pipe(
|
|
1505
|
-
// Effect.flatten,
|
|
1506
|
-
// Effect.withSpan(
|
|
1507
|
-
// command.action,
|
|
1508
|
-
// { captureStackTrace }
|
|
1509
|
-
// )
|
|
1510
|
-
// )
|
|
1511
|
-
// })
|
|
1512
|
-
// },
|
|
1513
|
-
/**
|
|
1514
|
-
* Define a Command for handling user actions with built-in error reporting and state management.
|
|
1515
|
-
*
|
|
1516
|
-
* @param id The internal identifier for the action. Used as a tracing span and to lookup
|
|
1517
|
-
* the user-facing name via internationalization (`action.${id}`).
|
|
1518
|
-
* @returns A function that executes the command when called (e.g., directly in `@click` handlers).
|
|
1519
|
-
* Built-in error reporting handles failures automatically.
|
|
1520
|
-
*
|
|
1521
|
-
* **Effect Context**: Effects have access to the `CommandContext` service, which provides
|
|
1522
|
-
* the user-facing action name.
|
|
1523
|
-
*
|
|
1524
|
-
* **Returned Properties**:
|
|
1525
|
-
* - `action`: User-facing action name from intl messages (useful for button labels)
|
|
1526
|
-
* - `result`: The command result state
|
|
1527
|
-
* - `waiting`: Boolean indicating if the command is in progress (shorthand for `result.waiting`)
|
|
1528
|
-
* - `handle`: Function to execute the command
|
|
1529
|
-
*
|
|
1530
|
-
* **User Feedback**: Use the `withDefaultToast` helper for status notifications, or render
|
|
1531
|
-
* the `result` inline for custom UI feedback.
|
|
1532
|
-
*/
|
|
1533
|
-
fn: <RT>(runtime: Runtime.Runtime<RT>) => {
|
|
1534
|
-
const make = makeCommand(runtime)
|
|
1535
|
-
return <
|
|
1536
|
-
const Id extends string,
|
|
1537
|
-
const State extends IntlRecord = IntlRecord,
|
|
1538
|
-
const I18nKey extends string = Id
|
|
1539
|
-
>(
|
|
1540
|
-
id: Id | { id: Id },
|
|
1541
|
-
options?: FnOptions<I18nKey, State>
|
|
1542
|
-
): Commander.Gen<RT, Id, I18nKey> & Commander.NonGen<RT, Id, I18nKey> & {
|
|
1543
|
-
state: Context.Tag<`Commander.Command.${Id}.state`, State>
|
|
1544
|
-
} =>
|
|
1545
|
-
Object.assign(
|
|
1546
|
-
(
|
|
1547
|
-
fn: any,
|
|
1548
|
-
...combinators: any[]
|
|
1549
|
-
): any => {
|
|
1550
|
-
// we capture the definition stack here, so we can append it to later stack traces
|
|
1551
|
-
const limit = Error.stackTraceLimit
|
|
1552
|
-
Error.stackTraceLimit = 2
|
|
1553
|
-
const errorDef = new Error()
|
|
1554
|
-
Error.stackTraceLimit = limit
|
|
1555
|
-
|
|
1556
|
-
return make(id, options, errorDef)(
|
|
1557
|
-
Effect.fnUntraced(
|
|
1558
|
-
// fnUntraced only supports generators as first arg, so we convert to generator if needed
|
|
1559
|
-
isGeneratorFunction(fn) ? fn : function*(...args) {
|
|
1560
|
-
return yield* fn(...args)
|
|
1561
|
-
},
|
|
1562
|
-
...combinators as [any]
|
|
1563
|
-
) as any
|
|
1564
|
-
)
|
|
1565
|
-
},
|
|
1566
|
-
makeBaseInfo(typeof id === "string" ? id : id.id, options),
|
|
1567
|
-
{
|
|
1568
|
-
state: Context.GenericTag<`Commander.Command.${Id}.state`, State>(
|
|
1569
|
-
`Commander.Command.${typeof id === "string" ? id : id.id}.state`
|
|
1570
|
-
)
|
|
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
|
|
1421
|
+
|
|
1422
|
+
if (cache !== false) {
|
|
1423
|
+
return cache
|
|
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
|
|
1571
1438
|
}
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
const command = Effect.withSpan(
|
|
1442
|
+
exec(...args).pipe(Effect.flatten),
|
|
1443
|
+
id,
|
|
1444
|
+
{ captureStackTrace }
|
|
1572
1445
|
)
|
|
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
|
+
})
|
|
1573
1480
|
},
|
|
1481
|
+
{ id }
|
|
1482
|
+
)
|
|
1483
|
+
}
|
|
1574
1484
|
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
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
|
+
)
|
|
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
|
+
)
|
|
1594
|
+
|
|
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>
|
|
1600
1616
|
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
customI18nKey?: I18nKey
|
|
1616
|
-
) =>
|
|
1617
|
-
& Commander.CommandContextLocal<Id, I18nKey>
|
|
1618
|
-
& (<Args extends Array<unknown>, A, E, R extends RT | CommandContext | `Commander.Command.${Id}.state`>(
|
|
1619
|
-
handler: (
|
|
1620
|
-
ctx: Effect.fn.Gen & Effect.fn.NonGen & Commander.CommandContextLocal<Id, I18nKey> & {
|
|
1621
|
-
// todo: only if we passed in one
|
|
1622
|
-
mutate: (...args: MutArgs) => Effect.Effect<MutA, MutE, MutR>
|
|
1623
|
-
}
|
|
1624
|
-
) => (...args: Args) => Effect.Effect<A, E, R>
|
|
1625
|
-
) => Commander.CommandOut<Args, A, E, R, Id, I18nKey>),
|
|
1626
|
-
|
|
1627
|
-
/** @experimental */
|
|
1628
|
-
alt: makeCommand as unknown as <RT>(
|
|
1629
|
-
runtime: Runtime.Runtime<RT>
|
|
1630
|
-
) => <const Id extends string, const I18nKey extends string = Id>(
|
|
1631
|
-
id: Id,
|
|
1632
|
-
customI18nKey?: I18nKey
|
|
1633
|
-
) =>
|
|
1634
|
-
& Commander.CommandContextLocal<Id, I18nKey>
|
|
1635
|
-
& (<Args extends Array<unknown>, A, E, R extends RT | CommandContext | `Commander.Command.${Id}.state`>(
|
|
1636
|
-
handler: (...args: Args) => Effect.Effect<A, E, R>
|
|
1637
|
-
) => Commander.CommandOut<Args, A, E, R, Id, I18nKey>),
|
|
1638
|
-
|
|
1639
|
-
/** @experimental */
|
|
1640
|
-
wrap: <RT>(runtime: Runtime.Runtime<RT>) => {
|
|
1641
|
-
const make = makeCommand(runtime)
|
|
1642
|
-
return <
|
|
1643
|
-
const Id extends string,
|
|
1644
|
-
Args extends Array<unknown>,
|
|
1645
|
-
A,
|
|
1646
|
-
E,
|
|
1647
|
-
R,
|
|
1648
|
-
const State extends IntlRecord = IntlRecord,
|
|
1649
|
-
I18nKey extends string = Id
|
|
1650
|
-
>(
|
|
1651
|
-
mutation:
|
|
1652
|
-
| { mutate: (...args: Args) => Effect.Effect<A, E, R>; id: Id }
|
|
1653
|
-
| ((...args: Args) => Effect.Effect<A, E, R>) & { id: Id },
|
|
1654
|
-
options?: FnOptions<I18nKey, State>
|
|
1655
|
-
):
|
|
1656
|
-
& Commander.CommandContextLocal<Id, I18nKey>
|
|
1657
|
-
& Commander.GenWrap<RT, Id, I18nKey, Args, A, E, R>
|
|
1658
|
-
& Commander.NonGenWrap<RT, Id, I18nKey, Args, A, E, R> =>
|
|
1659
|
-
Object.assign((
|
|
1660
|
-
...combinators: any[]
|
|
1661
|
-
): any => {
|
|
1662
|
-
// we capture the definition stack here, so we can append it to later stack traces
|
|
1663
|
-
const limit = Error.stackTraceLimit
|
|
1664
|
-
Error.stackTraceLimit = 2
|
|
1665
|
-
const errorDef = new Error()
|
|
1666
|
-
Error.stackTraceLimit = limit
|
|
1667
|
-
|
|
1668
|
-
const mutate = "mutate" in mutation ? mutation.mutate : mutation
|
|
1669
|
-
|
|
1670
|
-
return make(mutation.id, options, errorDef)(
|
|
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[]) =>
|
|
1671
1631
|
Effect.fnUntraced(
|
|
1672
1632
|
// fnUntraced only supports generators as first arg, so we convert to generator if needed
|
|
1673
|
-
isGeneratorFunction(
|
|
1674
|
-
return yield*
|
|
1633
|
+
isGeneratorFunction(fn) ? fn : function*(...args) {
|
|
1634
|
+
return yield* fn(...args)
|
|
1675
1635
|
},
|
|
1676
1636
|
...combinators as [any]
|
|
1677
|
-
)
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1637
|
+
),
|
|
1638
|
+
baseInfo,
|
|
1639
|
+
isObject
|
|
1640
|
+
? { mutate: "mutate" in _id ? _id.mutate : typeof _id === "function" ? _id : undefined }
|
|
1641
|
+
: {}
|
|
1642
|
+
)
|
|
1643
|
+
)), baseInfo) as any
|
|
1681
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)
|
|
1682
1703
|
})
|
|
1683
1704
|
}) {}
|