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 anAbortLineSignal
. Any BotAction can use and return the value from thecreateAbortLineSignal()
helper, used inabort()
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.
assembledLines | effect |
---|---|
0 | breaks the pipe and breaks restart |
1 | breaks 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) } }}