Making some more progress on the adding scripting of dynamo-browse. It helps being motivated to be able to write some scripts for myself, just to be able to make my own working life easier. So far the following things can be done within user scripts:

  • Define new commands
  • Display messages to, and get input from, the user
  • Read the attributes of, and set the attributes of, the currently selected row (only string attributes at this stage)
  • Run queries and get result sets, which can optionally be displayed to the user

Here’s a modified example of a script I’ve been working on that does most of what is listed above:

const db = require("audax:dynamo-browse");

db.session.registerCommand("cust", () => {
    db.ui.prompt("Enter user ID: ").then((userId) => {
        return db.session.query(`userId="${userId}"`);
    }).then((resultSet) => {
        db.session.currentResultSet = resultSet;
    });
});

db.session.registerCommand("sub", () => {    
    let currentItem = db.session.selectedRow;

    let currentUserId = currentItem.item["userId"];
    if (!currentUserId) {
        db.ui.print("No 'userId' on current record");
        return;
    }

    db.session.query(`pk="ID#${currentUserId}"`, {
        table: "billing-subscriptions"
    }).then((rs) => {
        db.session.currentResultSet = rs;
    });
});

The process of loading this script is pretty basic at the moment. I’ve added a loadscript command, which reads and executes a particular JavaScript file taken as an argument. Scripts can be loaded on startup by putting these loadscript commands (along with any other commands) in a simple RC file that is read on launch.

I’m not sure how much I like this approach. I would like to put some structure around how these scripts are written and loaded, so that they’re not just running atop of one another. However, I don’t want too much structure in place either. To me, having the floor for getting a script written and executed too high is a little demotivating, and sort of goes against the ability to automate these one-off tasks you sometimes come across. That’s the downsides I see with IDEs like GoLand and, to a lesser degree, VS Code: they may have vibrant plugin ecosystems, but the minimum amount of effort to automate something is quite high, that it may not be worth the hassle.

A nice middleground I’m considering is to make it to have two levels of automation: one using JavaScript, and the other closer to something like Bash or TCL. The JavaScript would be akin to plugins, and would have a rich enough API and runtime to support a large number of sophisticated use-cases, with the cost being a fair degree of effort to get something usable. The Bash or TCL level would have a lower level of sophistication, but it would be quicker to do these one-off tasks that you can bang out and throw away. This would mean splitting the effort between the scripting API and command line language, which would fall on me to do, so I’m not sure if I’d go ahead with this (the command line “language” is little more than a glorified whitespace split at the moment).

In the meantime, I’ll focus on making sure the JavaScript environment is good enough to use. This will take some time and dog-fooding so they’ll be plenty to do.

I’ve also started sharing the tool with those that I work with, which is exciting. I’ve yet to get any feedback from them yet, but they did seem quite interested when they saw me using it. I said this before, but I’ll say it again: I’m just glad that I put a bit of polish into the first release and got the website up with a link I can share with them. I guess this is something to remember for next time: what you’re working on doesn’t need to be complete, but it helps that it’s in a state that is easy enough to share with others.