Skip to content

Latest commit

 

History

History
executable file
·
334 lines (236 loc) · 11.8 KB

NOTES.md

File metadata and controls

executable file
·
334 lines (236 loc) · 11.8 KB

Status

Stability: Beta

Summary

The loader is currently under active development. Production use is possible if releases are thoroughly tested prior to use. APIs may slightly change in future.

Contributors

Looking for:

  • Users to use the loader and report issues
  • Adapter authors for other CommonJS platforms
  • Critical reviewers for specifications
  • Feedback in all areas
  • Contributions in any area

TODO

General

  • Support for: http://www.phantomjs.org/

  • Do not throw if package does not have "main" set and --script is used

  • OS distro packages for loader

  • Author: CommonJS Programs/A (strawman)

  • Author: PINF Workspace/A (strawman)

  • Enforce reserved names for mapping labels based on default modules provided by platform

  • Build and publish commands to provide versioned releases (This will be part of PINF/CLI)

  • Rename ./lib/pinf-loader-js to ./lib/pinf-loader

  • Path resolution in config files files:

    • /from/THIS/PACKAGE/root
    • ./relative/to/CONFIG/FILE
    • from/TOP/PACKAGE/root config files get merged and path gets resolved from seed config file.

NodeJS

  • Get ./lib/modules/pinf/protocol-handler.js working

Jetpack

  • warning: undeclared require(widget) called from ...

  • CLI variables and arguments

  • Package parsing to find widgets etc... for security policy stuff

  • Downloading program archives based on mappings

  • Resource path resolving for packages

  • Hook package testing into cfx test

BravoJS Comments

  • All internal top-level module paths for packaged modules follow @/ where '@/' is used to signify the package root.

  • Expanded scope of module.load(s, f) to allow a mappings object for 's'.

  • Expanded scope of module.declare([], f) to allow labelled mapping objects for '[]'.

  • Changed module.load(id/mapping, function(id) { ... }) to return the canonical ID of the loaded module that can be used with require(id).

  • Added chained plugin system to service resolvePackageMapping(packageMapping) which must return a top-level package ID if it can resolve.

  • Added module.pkgId which is set to the ID of the containing package for a module if the module is part of a package.

  • Added module.mappings which is set to a resolved map where values are top-level package IDs for a module if the module is part of a package with mappings.

  • Map package UID as valid package ID (in addition to path-basd package ID) if package descriptor has uid property set.

  • Ability to resolve modules by @/ if the package descriptor has the "uid" property set. e.g. require("http://registry/hostname/path/package1/@/lib/main") This is not ideal as one must know the in this case 'lib/main'. A better solution may be: require("http://registry/hostname/path/package1/@/").resolve("main"); Where '@/' is used to signify that we want to load a special object that can resolve IDs for the specified package ID.

  • Relative dependency IDs for module.declare() were resolved based on bravojs.mainModuleDir whereas they should be resolved based on the path of the module.

  • The spec could use more wording as to whether functions accept relative and/or absolute module identifiers only.

  • The modules property for package.json is only partially supported and module IDs (keys) must be normalized on server prior to loading.

Specification Comments

CommonJS System

  • Need SYSTEM.os <- uname

Additions:

  • Need a property to identify the platform in order to load correct platform API modules.

  • require("./lib/platform/{platform}/main") where {platform} is replaced with require.platform

  • Need a way to print to stdout no matter what. Especially important in browser where window.print. should not be over-written. Proposed: module.print

  • New module.pkgId property

  • New module.hashId property

  • New require.pkg(<packageID>).id(<moduleId>). If no argument for id() the package ID is returned. If true as second argument to .id() the ID is returned unsanitized (context delimiters stay in tact)

  • There may not be any delimiters in the pathIDs given by module.id, module.pkgId

  • Need facility to get command line arguments

Changes:

  • Section 5.2.1: Environments that do not support searchable module paths must set require.paths[0] to the mainModuleDir.

  • If true as second argument to require.id() the ID is returned unsanitized (context delimiters stay in tact)

Additions:

  • uid property must end in /.

  • uid property must be a non-resolving or resolving URL.

  • uid may resolve to a catalog covering the different release branches of the package.

  • uid may resolve to a registry namespace.

  • native boolean to indicate that modules should be treated as-is (i.e. the package contains modules written for the host platform where require() provided by intermediate loaders should be bypassed at all times and modules should not be wrapper or altered in any way.)

  • preload array to hold list of moduleIDs for modules to call when initializing package. If moduleId starts with ./ the ID is relative to the package root. If not it is relative to directories.lib The main() function of each module is called passing a context object. The main() function may return an object with keys mapping functions to specific hooks.

Notes:

  • overlay property with keys: pinf:{platform}

Additions:

  • Mapping labels may not begin with '_' which is reserved for loaders to map special namespaces.
  • Catalog URLs (and any other descriptor URLs) must end in .json to be able to distinguish from <packageUID>

Verify alternate mapping locators:

locator: "/<packagePath>"
locator: "<archiveURL>"
locator: "jar:<archiveURL>!/path/to/package"
locator: {
    location: "/<packagePath>"
}
locator: {
    location: "<relativePath>"
}

locator: {
    catalog: "<catalogURL>",
    name: "<packageName>"
}

locator: {
    name: "<packageName>",
    version: "<packageVersion>",
    pm: "<packageManager>"      // e.g. "npm"
}


// `archive`-based locators are URLs that must point to a ZIP archive

locator: {
    archive: "<archiveURL>"
}
locator: {
    archive: "jar:<archiveURL>!/path/to/package"
}

// specifying modules

locator: {
    module: "<moduleId>"
}
locator: {
    module: "./<modulePathId>"
}
locator: {
    module: "/<modulePathId>"
}

// indicate that a mapping (or module) is not available
// causes require() to throw
locator: {
    available: false
}

Top-level ID lookup rules when deriving IDs from mapping properties:

  • Check for matching id
  • Check for matching uid
  • Check for matching uid + version
  • Check for matching uid + revision
  • Check for matching location

New: Module Mappings

package.json ~ {
    "modules": {
        "module3": {
            "id": "github.com/pinf/loader-js/demos/MapModule/",
            "module": "new-module3"
        }
        "/lib/module3": {},
        "./lib/module3": {}
    }
}
  • Before module IDs are finalized they are matched against the modules property.

  • The keys are prepended with directories.lib (if not prefixed with './' or '/') and matched against the final module IDs for the package.

  • If a match is found the mapped module is used instead.

  • Resolve mapped module URLs. For example:

    "code.jquery.com/": {
        "locator": {
            "location": "http://code.jquery.com/jquery-1.6.4.min.js"
        },
        "descriptor": {
            "uid": "http://code.jquery.com/",
            "directories": false
        }
    }
    

    Where "directories": false specifies that locator.location points to a URL containing a module in plain text.

CommonJS Programs/A

  • A program is booted by calling the package listed for boot

    • NOTE: Multiple boot packages (specified as array) are partially supported but will likely be phased out as there are too many side-effects
  • All packages listed in boot must have matching keys in packages

  • Only packages listed in packages may be loaded into the program

  • Only packages listed in boot (and associated dependencies) are loaded into the program at boot time

  • Additional packages may be loaded into program if listed in packages

  • Load contexts to avoid adding already loaded modules to transport files. E.g.: "contexts": { "top": { "github.com/pinf/loader-js/demos/ACE/editor/@/main": { "include": { "github.com/ajaxorg/pilot/@/lib/pilot/index": {}, "github.com/ajaxorg/ace/@/lib/ace/defaults": {}, "github.com/ajaxorg/cockpit/@/lib/cockpit/index": {} }, "load": { "github.com/ajaxorg/ace/": {} } }, "github.com/pinf/loader-js/demos/ACE/worker/@/worker": { } } }

Top-level ID formats

/<packagePath>@/<resourcePath>
<packageUID>@/<resouecePath>
<catalogURL>/<packageName>@/<resouecePath>

Where:

  • <packagePath> is the UNIX path to a package root directory (no trailing slash, absolute path implied).
  • <resourcePath> is the UNIX path to a resource in the package from the package root (no beginning slash).
  • <packageUID> - is the uid property from package.json without http:// prefix.
    • If hostname (uid property is a URL) is a known registry server it is dropped as a prefix as well leaving the registry namespace as the <packageUID>.

Other

  • require() must look to platform require() to resolve top-level IDs that do not resolve within the loader
    • Actually if a module ID does not resolve locally or via a mapping it should fail
  • dependencies for native modules no longer supported

Jetpack Wishlist

  • Get current working directory path
  • Get environment variables
  • Get command-line arguments
  • Keep positioning and size of last test/run profile and apply to new profiles

Links