Actions
Actions are the core of BeDoc’s functionality. There are two kinds:
- Parsers read source files and produce a structured object.
- Formatters take that structured object and render it into an output format (Markdown, Wikitext, …).
An action is a JavaScript file that default-exports a class. That class declares a little metadata and describes its work as a pipeline. BeDoc discovers the action, negotiates its contract against a partner action, instantiates it, and runs the pipeline over each file.
Anatomy of an action
Section titled “Anatomy of an action”Every action class has exactly two required members:
static meta— describes what the action is and points at its contract.setup— an arrow function that receives anActionBuilderand configures the processing pipeline.
import { ActionBuilder, ACTIVITY } from "@gesslar/actioneer"
export default class MyParser { static meta = Object.freeze({ kind: "parser", input: "lua", terms: "ref://./my-parser.yaml", })
setup = builder => builder .do("Extract blocks", this.#extractBlocks) .do("Process functions", ACTIVITY.SPLIT, ctx => ctx, // splitter ctx => ctx, // rejoiner new ActionBuilder() .do("Extract signature", this.#extractSignature) .do("Extract description", this.#extractDescription), ) .done(this.#finally)
#extractBlocks = ctx => { /* … */ } #extractSignature = ctx => { /* … */ } #extractDescription = ctx => { /* … */ } #finally = ctx => ({ functions: ctx })}static meta
Section titled “static meta”meta is a frozen object. The required fields depend on the kind.
static meta = Object.freeze({ kind: "parser", // required input: "lua", // required — the language this parser reads terms: "ref://./my-parser.yaml", // required — path to the contract})static meta = Object.freeze({ kind: "formatter", // required format: "markdown", // required — the format this emits extension: "md", // required — output file extension terms: "ref://./my-formatter.yaml", // required — path to the contract})| Field | Applies to | Meaning |
|---|---|---|
kind |
both | "parser" or "formatter". |
input |
parser | The language identifier matched against --language. |
format |
formatter | The output format matched against --format. |
extension |
formatter | Extension used for written output files (e.g. md). |
terms |
both | A ref:// path to the action’s contract YAML/JSON file, resolved relative to the action file. |
The pipeline
Section titled “The pipeline”Instead of a single run() method, an action describes its work as a chain of
named steps using the fluent
ActionBuilder API
from Actioneer. The setup field is an arrow
function (so this is the action instance) that receives the builder and
returns it configured:
setup = builder => builder .do("Step name", this.#stepMethod) .do("Another step", this.#anotherMethod) .done(this.#finalize).do(name, fn)adds a step. Each step receives the current context (ctx) and returns the context for the next step..do(name, ACTIVITY.SPLIT, …)fans the context out into items, runs a sub-pipeline over each (in parallel, up to--maxConcurrent), then rejoins the results..done(fn)registers the final step that produces the action’s result.
The step names matter: they are the anchor points for
hooks. A step named "Format function" can be wrapped by a
before$formatFunction / after$formatFunction hook (the hook name is the
camelCase of the step name).
What a parser produces / a formatter consumes
Section titled “What a parser produces / a formatter consumes”A parser’s pipeline ends by producing the structured object promised by its
contract — typically { functions: [ … ] }. That object is handed to the
matched formatter, whose pipeline renders it to a string. The shape of that
object is governed by the contract the two actions
negotiate.
Logging
Section titled “Logging”Actions are not handed a logger instance — there is no this.log on your
action. BeDoc’s own debug output is controlled by the --debug /
--debugLevel configuration options.
Packaging
Section titled “Packaging”A single action file default-exports a single action. To ship one or more
actions as an installable package, list the files under a bedoc.actions array
in your package.json so BeDoc can discover them:
{ "name": "bedoc-mylang-parser", "version": "1.0.0", "type": "module", "bedoc": { "actions": ["./bedoc-mylang-parser.js"] }}See the Modules guide for packaging and naming conventions, and the Parsers and Formatters guides for end-to-end examples.
Actions expose their named steps as hook points, letting users
inject custom logic with before$/after$ handlers — without touching the
action itself.
Read the Hooks Guide to learn more.
