Botmation Documentation

Abort

Abort

These BotAction's focus on returning an AbortLineSignal. The signal's purpose is to inform the assembling BotAction to break the assembled line, to return early. However, the signal itself can be processed in any way needed. Therefore, to understand how the AbortLineSignal works in a bot, it has to be seen in the context of each Assembler as some have unique behavior.

To learn more about aborting, read the Advanced Aborting documentation.

Abort

This BotAction simply returns an AbortLineSignal based on the params provided with safe fallbacks for no params. The default AbortLineSignal has no pipeValue and is set to abort only one line of assembly.

It is not necessary to use the abort() BotAction to return an AbortLineSignal. Any BotAction can use and return the value from the createAbortLineSignal() helper, used in abort() BotAction.

const abort = (assembledLines = 1, pipeValue?: PipeValue): BotAction<AbortLineSignal> =>
async() => createAbortLineSignal(assembledLines, pipeValue)

For a practical example, see abortPipe().

Restart

This BotAction is similar to pipe()(), except it will restart when an assembled BotAction returns an AbortLineSignal with assembledLines = 1 (default count). In this event, it takes the pipe value from the AbortLineSignal then injects it into the first assembled BotAction, before running the assembled BotActions in a pipe again.

You can use Restart to rerun assembled BotActions with a different initial pipe value, by aborting with an assembledLines count of one, as many times as you need.

const restart = (...actions: BotAction<any>[]): BotAction<any> =>
async(page, ...injects) => {
let pipeObject: Pipe = createEmptyPipe()
if (injectsHavePipe(injects)) {
pipeObject = getInjectsPipeOrEmptyPipe(injects)
injects = injects.slice(0, injects.length - 1)
}
let restartActions: boolean
let actionResult: AbortLineSignal|PipeValue|undefined
do {
restartActions = false;
for(const action of actions) {
actionResult = await action(page, ...injects, pipeObject)
if (isAbortLineSignal(actionResult)) {
if (actionResult.assembledLines > 1 || actionResult.assembledLines === 0) {
return processAbortLineSignal(actionResult, 2)
} else {
restartActions = true;
pipeObject = wrapValueInPipe(actionResult.pipeValue)
break;
}
}
pipeObject = wrapValueInPipe(actionResult)
}
} while(restartActions)
return actionResult
}

Both the Infinite AbortLineSignal and assembledLines count of two or more will fully abort Restart. The sweet spot for restarting BotActions is with the default assembledLines count of one.

assembledLineseffect
0breaks the pipe and breaks restart
1breaks the pipe, then restarts the BotActions with the AbortLineSignal's pipe value injected
2+breaks the pipe and breaks the restart

Here is an example with a made-up BotAction called goToPipeValue() that would use the pipe value as the URL, to navigate too before running the subsequent BotActions:

await pipe('http://initial-url.com')(
restart(
goToPipeValue,
// .. do the scraping, etc
abortWithDifferentUrl
)
)(page)

In this case, all the BotActions after goToPipeValue could do a common routine of scraping web-content, followed by a dynamic abort, which causes the restart with a different URL, each time.

Abort Pipe

This BotAction returns an AbortLineSignal if the value provided matches the pipe object's value. value can be a function, which then is called as a Conditional Callback with the pipe object's value. If the callback returns truthy, it will return an AbortLineSignal.

By default, the AbortLineSignal returned has an assembledLines count of 1, but can be overriden with the optional second parameter.

If the value doesn't match the pipe object's value (including function), then a CasesSignal is returned.

const abortPipe = (value: CaseValue, abortPipeValue: PipeValue = undefined, assembledLines: number = 1): BotAction<AbortLineSignal|PipeValue|CasesSignal> =>
pipeCase(value)(
abort(assembledLines + 2, abortPipeValue)
)

Here's an example:

await switchPipe('some-value')(
abortPipe('bad-value'), // unsupported, unhandled, error prone case, etc just abort
pipeCase('some-value')(
// this value is supported and will match therefore cause this line to run
)
)(page)

Helpers

createAbortLineSignal()

Simple function to create an AbortLineSignal object with safe defaults for no params. No params provided yields an AbortLineSignal with 1 assembledLines to break, no pipeValue.

const createAbortLineSignal = (assembledLines = 1, pipeValue?: PipeValue): AbortLineSignal => ({
brand: 'Abort_Signal',
assembledLines: Math.abs(assembledLines),
pipeValue
})

processAbortLineSignal()

Simple helper function for BotAction's that assemble other BotAction's that may need to process an AbortLineSignal object. Default case is to reduce the AbortLineSignal assembledLines count by 1, unless it's count is 1 or 0. On 1, return the AbortLineSignal pipeValue and on 0, return the AbortLineSignal as is, for the infinity case.

If the optional second param reduceAssembledLinesBy is set to a number greater than the assembledLines count of the AbortLineSignal, it simply returns the pipeValue.

const processAbortLineSignal = (abortLineSignal: AbortLineSignal, reduceAssembledLinesBy = 1): AbortLineSignal|PipeValue => {
switch(abortLineSignal.assembledLines) {
case 0:
return abortLineSignal
case 1:
return abortLineSignal.pipeValue
default:
if (abortLineSignal.assembledLines < reduceAssembledLinesBy) {
return abortLineSignal.pipeValue
} else {
return createAbortLineSignal(abortLineSignal.assembledLines - reduceAssembledLinesBy, abortLineSignal.pipeValue)
}
}
}
Edit this page on GitHub
Baby Bot