jsish
Packages
Not logged in

Packages

A package is software (javascript or compiled extension) containing a provide().

Packages are loaded using require().

Here is a javascript example:

//File: simple.jsi
function simple(n) { return n+1; }

provide('simple');

and this is loaded with:

require('simple');

simple(2);

Note, javascript packages are typically deployed as modules.

Provide

function provide(name:string, version:number=1):void

provide indicates that the current file supplies name for a require.

A package file is of the form name.EXT or name/name.EXT; name may contain only the characters _ 0-9 a-z A-Z.

This file is either a Jsi script (.jsi) containing a provide(name) call, or shared library (.so/.dll) containing a Jsi_PkgProvide().

Require

function require(name:string=void, version:number=1):number|array|object

Require is used to load/query packages:

If a version argument is given, and it is greater than package version, a warning is generated.

Package files are searched for in the following paths:

  1. Any directory in the pkgDirs Interp option.
  2. The executable directory of jsish.
  3. The directory of the current script.

PkgDirs

Packages are searched for are specified by pkgDirs, which can be set pkgDirs using:

Interp.conf({pkgDirs:['/usr/local/lib', '/usr/share']});

When a package is not found in pkgDirs, the executable and main script directories are checked.

Note: sub-interps inherit pkgDirs from the parent.


Load

function load(shlib:string):void

The load command is used to load shared library extension into memory.

load('libsqlitejs.so');

On Windows, the extensions .dll is used instead of .so.

For more details see Extensions.


Source

function source(val:string|array, options:object=void):void

source is used to include javascript files, eg.

source('scripts/foo.js');

source will also accept an array of files, as in:

source(['foo.js','bar.js']);

A second parameter may be used for setting the following options:

Option Type Description
debugINTDebug level.
autoBOOLSetup for load of autoload.jsi files.
isMainBOOLSet Info.isMain() to true.

Various source related options can be configured/examined in the usual way:

Interp.conf({maxIncDepth:10});
var cur = Info.script();
var dir = Info.scriptDir();

The above changes the recursive maximum depth of source from it's default of 100.


Autoload

Because it is sometimes desirable to defer loading code until first invocation, Jsi provides a mechanism using member values in the object Jsi_Auto to evaluate. For example, given the file myfunc.js:

// File myfunc.js
provide('myfunc');
function double(n) { return n*2; };
function half(n)   { return n/2; };

We can arrange for dynamic sourcing with:

Jsi_Auto.double =
Jsi_Auto.half   = 'require("myfunc");';

double(4); // Load is triggered!
half(4);

This also works for object commands:

Jsi_Auto.MySql = "require('MySql')";

//...
var db = new MySql({user:'root', database:'jsitest'});

AutoFiles

Jsi_Auto can be dynamically setup.

When Jsi first tries to invoke an undefined function, it first traverses a list of files given in the interp option autoFiles.

The default jsish value is:

# Interp.conf('autoFiles');
[ "/zvfs/lib/autoload.jsi" ]

Which means it loads the file ../lib/autoload.jsi, usually from the self-mounted Zip-FS on /zvfs.

After this Jsi_Auto members are accessed to load the function.

Additionally, if an application is run from a .zip file, it's autoload.jsi file gets added to autoFiles automatically.

This 2-stage approach results in no overhead, until a function call fails.

Object Functions

Autoloading non-constructor object functions can use the following approach (the example ignores the fact that JSON is not actually loadable):

var JSON = { 
   parse:     function() { require('JSON'); return JSON.parse.apply(this,arguments); },
   stringify: function() { require('JSON'); return JSON.stringify.apply(this,arguments); }
   //...
}
JSON.parse(str); // Load is triggered!

Although that works, it suffers from one problem: the first call will not type-check functions.

We could fix this shortcoming with:

var JSON = {
    check: function(str:string, strict:boolean=false):boolean { require('JSON'); return JSON.check.apply(this,arguments); },
    //...
};

But correctly transcribing function signatures is more complicated.

Fortunately there is a helper function:

function Jsi_AutoMake(objName:string):string

which can be used to generate the auto file:

File.write( Jsi_AutoMake('JSON'), 'autoload.jsi');

The file autoload.jsi now contains calls and load and type-check correctly:

var JSON = {
    check: function(str:string, strict:boolean=true):boolean { require('JSON'); return JSON.check.apply(this,arguments); },
    parse: function(str:string, strict:boolean=true):any { require('JSON'); return JSON.parse.apply(this,arguments); },
    stringify: function(obj:object, strict:boolean=true):string { require('JSON'); return JSON.stringify.apply(this,arguments); },
};