NPDS Scripting Architecture

Introduction

During development of NPDS 2.0, I recieved a constant stream of requests for custom Server Side Includes. However, since every SSI added means additional parsing time, I couldn't very well add in lots of neat (but often of dubious usefulness) items like temperature, Longitude & Latitude, owner's Birthday, eand so on since not everyone would use them.

My answer to providing custom SSI is the NPDS Simple Scripting Architecture.

I've added the ability to link text-based scripts to user-defined TOKENs. These scripts can return text values (most common) or can execute actions on the host machine. All that is required is a minimum of Newtonscript knowledge and/or the ability to follow the example scripts packaged with Script Editor.

Script Editor

On the right is a screenshot of your interface to NPDS Scripting, the Script Editor. The UI elements are as follows:

 

Writing Scripts

A NPDS Script is cast as a standard Newtonscript function that returns some value. Since most of what NPDS is used for is text-based, most NPDS Scripts should return Text.

1. Open Script Editor and tap the "New Script" Button.

2. Enter the Following Text (Note that some of it is already written for you on the Notepad)

func(nullvar)

begin

local theOutput:= "NewtonOS ROM Version:" && Gestalt(0x1000003).ROMversionstring;

return theOutput;

end

3. Tap on the "Script Info" Box and enter a Name and SSI for this script. If you wish it to be available to NPDS right away, tap the "Script Is Active" checkbox. You may activate and inactivate scripts at will simply by changing the value of this checkbox.

4. Let's try this function out: Tap "Evaluate". You'll get a window that should give you either the text output of your function (or a cryptic error message and the Newtonscript Error Code).

Your Example Worked but What Do I Need to Know to Write My Own?

Dummy Variable

Look at the head of the script: "func(nullvar)". The nullvar is a dummy variable that is required by NPDS's Compiler. You can change its name, but the fact remains that a NPDS Script must accept ONE and ONLY ONE argument. You cannot pass your own arguments to your script. (There is a way around this that I'll mention later)

Script Length

There is a limit on the length of NPDS Scripts to encourage you to write FAST and efficient code and currently that limit is 1024 Bytes.

Compiler Symbols

1024 Bytes isn't a lot, especially in light of the fact that in order to command, for instance, nHTTPd, you usually need lengthy code like

GetRoot().|nHTPd:ALLPEN|

In anticipation of this, and also to save some typing, the NPDS Compiler supports symbols that stand for specific expressions.

The current list of symbols and their values (Symbol : Value)

Script Execution Time

When you Evaluate a script, also present in the results window will be a count of Ticks required for compiling and execution of your code. Script Editor will complain if your code takes longer than 300 Ticks (6 Seconds) to Execute.

While there is no limit on the size of function you create, keep in mind that when a NPDS Script is invoked, it is parsed, compiled, and evaluated on the fly during service of the page that invokes it. A script that takes 300 Ticks to run will add 6 seconds to the 1-4 seconds its takes NPDS to serve a page for a total of up to 10 seconds. Many browsers will time out at 10 seconds and close their connections. Hence the suggestion of keeping your scripts short and sweet...

If you want real POWER, learn the NPDS API and write your own custom plugins. With my user proto and documentation you can create a simple NPDS plugin in an afternoon, with the limiting step being your ability to write your own data generation functions.

Limit on Output Size

Currently, the NPDS Compiler returns only 1000 bytes of any function result. If your output is longer than 1000 bytes it will be truncated. This may change in the future, but for now consider it additional impetus to learn the NPDS API if you need to generate large outputs.

 

FAQ

Q: How many Scripts should I keep active at a given time?

A: Well, when a script is "Active", NPDS output is scanned for the presence of the SSI assigned to that scripts. This takes a couple of ticks per SSI. Not until an instance of the SSI is found is the script actually evaluated. However, since we're trying to keep things fast, I'd suggest no more than 10 User scripts active at any given time.

Q: How do I access items such as the current user's IP address, the name of the file being requested, etc?

A: During HTTP Request, nHTTPd fills a slot called current_http_request with the following frame

{ip: user's IP address (string),

path: the directory and filename requested (string),

time: time in seconds of the request (integer)}

To access these items, use the following: |NPDS|.current_http_request.slot

Q: The text output of my script is cut off.. why?

A: There is a limit of 1000 bytes on text returned from a NPDS Script

Q: What is that "Script Returns a Static Value" option?

A: NPDS keeps its speed despite the additional features we keep adding by doing a lot of pre-processing and cacheing. Some of NPDS' own SSI are evaluated only at Startup and are held in memory throughout the lifetime of the session.

This option within the Scripting Architecture is similar in function, but is not yet implemented. If you have scripts that will return a static value (say, the Latitude and Longitude of your City), you can check this option and when support for pre-evaluation is included in NPDS, your scripts will run much faster.