Genii Weblog

A bigger boat: meeting developers where they are

Wed 8 Apr 2020, 11:25 AM



by Ben Langhinrichs
Inline JPEG image
 
In my previous post, A bigger boat: growing the vision for Domino development, I introduced the idea (with a demo!) of an extensive set of Notes/Domino functionality exposed in different ways, in this case LotusScript and JavaScript with Node.js. The idea is that we need Domino API functionality available where projects are. If a company is using Node.js extensively, we need that functionality there, not in LotusScript. But if a company has invested a lot in LotusScript, we need the functionality there. Likewise, while we might wish everybody would rush to Domino 11, there are companies on 8.5.3, 9.0.1, 10, and 11. We need to reach them where they are if we want widespread adoption,
 
In this post, I wanted to talk about lower level ways in which we reach the developer where she or he is. Some developers are used to LotusScript, so we'd like to make it easy for them to translate their skills even if they have to work in JavaScript. Other developers are coming to this with extensive JavaScript skills, and we'd like to make it easy for them as well. Additionally, there are strengths in JavaScript we don't have in LotusScript, and we'd like to make those available.
 
Let's look at an example:
 
Parameters
rtchunk.appendText("Duck season!", 12, "Bold 12pt");
rtchunk.appendNewLines(1, false);
rtchunk.appendText("Rabbit season!", 14, "Bold 12pt");
rtchunk.appendNewLines(1, true);
 
In LotusScript, methods are called with a series of defined parameters. Some parameters are required, while others are optional. One of the design decisions we made with Exciton Power is to provide more options rather than fewer. It is a risk, as people could get confused or wonder which is "correct", though under a very thin layer, the choices do exactly the same thing. So, we provide the option of using LotusScript-style parameters and validating them the way we would in LotusScript.
 
Objects
But JavaScript developers are often more comfortable with objects, both unnamed and relatively unstructured objects and objects which are part of defined classes. This could could be written as objects using:
rtchunk.appendText({text: "Duck season!", textLen: 12, fontSpecs: "Bold 12pt"});
rtchunk.appendNewLines({count: 1, newParagraph: true});
rtchunk.appendText({text: "Rabbit season!", textLen: 14, fontSpecs: "Bold 12pt"});
rtchunk.appendNewLines({count: 1, newParagraph: true});
 
Slightly more self-documenting, but not terribly different. But let's name those objects and see some differences:
 
var txtObj = {fontSpecs: "Bold 12pt"};
var nlObj = {count: 1, newParagraph: false};
 
txtObj.text = "Duck season!";
txtObj.textLen = txtObj.text.length;
rtchunk.appendText(txtObj);
 
nlObj.newParagraph = 
rtchunk.appendNewLines(nlObj);
 
txtObj.text = "Rabbit season!";
txtObj.textLen = txtObj.text.length;
rtchunk.appendText(txtObj);
 
nlObj.newParagraph = true
rtchunk.appendNewLines(nlObj);
 
At first glance, this is even longer and less clear, but we have separated out how we set the font specs so that can be handled elsewhere according to some other rule, and changed the logic so the textLen property can be calculated instead of hard-coded. We could then take this another step further, and make the txtObj a class where the txtLen was calculated automatically when the text was set, and you could separate out setting point size from setting other attributes, for exampe. 
 
class TextObj {
  constructor() {
    this.ptSize = "10pt";
    this.attribs = "Plain";
    this.color = "Black";
    this.face = "sans-serif";
    this.fontSpecs = this.ptSize+" "+this.attribs+" "+this.color+" "+this.face;
  }
  setText(t) {
    this.text = t;
    this.textLen = this.text.length;
  }
  setPtSize(pt) {
    this.ptSize = pt;
    this.fontSpecs = this.ptSize+" "+this.attribs+" "+this.color+" "+this.face;
  }
}
 
var txtObj = new TextObj();
var nlObj = {count: 1, newParagraph: false};
 
txtObj.setText("Duck season!");
rtchunk.appendText(txtObj);
 
nlObj.newParagraph = 
rtchunk.appendNewLines(nlObj);
 
txtObj.setText("Rabbit season!");
rtchunk.appendText(txtObj);
 
nlObj.newParagraph = true
rtchunk.appendNewLines(nlObj);
 
 
With classes, you can implement rules so that certain things are and aren't allowed. Obviously, all of this can be done in LotusScript in a more cumbersome way, but we wanted to meet JavaScript developers where they are and also take advantage of individual language strengths. With the option of either explicit parameters or a JavaScript object, we go to war with the army we have, whatever army we happen to have.
 
 
If you would be interested in participating in the Exciton beta, or even if you just have questions, contact me by e-mail at 
 

Copyright © 2020 Genii Software Ltd.

What has been said:


1119.1. Dan
(04/08/2020 02:26 PM)

What does the network traffic look like between node and the domino server?

Or is this intended to be used on-box?


1119.2. Ben Langhinrichs
(04/08/2020 02:49 PM)

Dan, this version is implemented like a standalone Notes API product using NRPC and the same network traffic (basically) as you would expect from a Notes client running LotusScript. (In other words, the Notes doc gets pulled into memory and manipulated and later written back to the local db or server db.)

There is a gRPC version we are still working on that will look basically identical inside Node but will work with a PROTON-like addon for the server. We are still determining which is better for on-box server use, but the gRPC version will certainly be necessary (just like domino-db) for clients where the Notes libraries are not available.