jesta

🃏 Stencila plugin for executable documents using JavaScript

https://github.com/stencila/jesta

Science Score: 26.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (13.8%) to scientific vocabulary

Keywords

documents executable javascript nodejs
Last synced: 4 months ago · JSON representation

Repository

🃏 Stencila plugin for executable documents using JavaScript

Basic Info
  • Host: GitHub
  • Owner: stencila
  • License: apache-2.0
  • Language: TypeScript
  • Default Branch: main
  • Homepage:
  • Size: 1.31 MB
Statistics
  • Stars: 2
  • Watchers: 2
  • Forks: 0
  • Open Issues: 11
  • Releases: 23
Topics
documents executable javascript nodejs
Created almost 5 years ago · Last pushed 5 months ago
Metadata Files
Readme Changelog License Codemeta

README.md

🃏 Jesta

Stencila plugin for executable documents using JavaScript


Build Status Coverage NPM Docker Image Docs

✨ Features

  • Implements compile, build and execute methods for CodeChunk and CodeExpression nodes with Javascript as their programmingLanguage.

  • Implements vars, get, set and delete methods for managing variables in Node.js.

  • Implements funcs, and call methods for using functions defined in Node.js.

  • Implements decode and encode methods for document format json.

  • Implements select for query language simplepath.

  • Implements read and write for protocols file://, http:// (with RFC 7234 compliant caching), and stdio://.

  • Implements the validate method to validate documents against Stencila JSON Schema. By default, coerces inputs to meet the schema (e.g. dropping unknown properties, parsing dates) but this can be turned off with --force=false.

  • A base for other plugins written in Javascript or Typescript (implements manifest and serve methods required for integration with Stencila CLI and Desktop)

  • A simple command line interface, including interactive modes, for running and testing plugins.

🏗️ Roadmap

  • [x] Development setup (linting, tests, CI, docs etc)
  • [x] Semantic releases
  • [x] Simple API for developing extension plugins
  • [x] Simple CLI for testing extension plugins
  • [x] Binary distributions using pkg (mainly as an example for extenders)
  • [ ] Add js as a format for encoding and decoding (with basic comment parsing)
  • [x] Docker image (mainly as an example for extenders)
  • [x] Re-implement / move basic IO utility functions from Encoda (e.g. cached HTTP requests, MediaType mappings)
  • [ ] Finish implementing core execution functions for Javascript: compile, build, execute, funcs, call.
  • [ ] Implement set for Parameter nodes
  • [ ] Use logga for logging
  • [ ] At least 95% test coverage
  • [ ] Complete implementing manifest
  • [ ] Test usage with stencila CLI
  • [x] Add an 🙏 Acknowledgements section to this README

📦 Install

Via stencila

This is the default plugin for using Javascript with Stencila. Install it using the Stencila CLI,

sh stencila plugins install javascript

Or using the name of this repo directly,

sh stencila install jesta

Via npm

If you have Node.js and NPM installed,

sh npm install --global @stencila/jesta

Via docker

A Docker image is built for each release,

sh docker pull stencila/jesta

🚀 Use

Most of the time you won't use Jesta directly (it's more likely that you will use one of the plugins extended from it, or use it via the Stencila CLI).

But if you do want to run Jesta standalone, for example to execute a document containing Javascript code,

sh jesta execute document.json

Or, if you are using the Docker image,

sh docker run -it --rm -v$PWD:/work -w/work stencila/jesta execute document.json

💪 Extend

Jesta is designed to be extended so that you can create your own Stencila plugins using Javascript or Typescript.

Getting started

Initialize your package and add Jesta as a dependency:

sh npm init npm install @stencila/jesta

Override one or more method

Override any of Jesta's methods e.g. compile and in your index.ts or index.js, call Jesta's cli function e.g.

```ts import { Jesta } from '@stencila/jesta' import { compile } from './compile'

export class MyPlugin extends Jesta { compile = compile }

if (require.main === module) new MyPlugin().cli() ```

Write a codemeta.json file

The codemeta.json file contains metadata (based on the Codemeta and schema.org standards) about your plugin including how it can be installed and it's capabilities. This metadata is used by Stencila to determine how it should install your plugin, how to run it, and what functions should be delegated to it.

A good place to start is by copying Jesta's codemeta.json file and modifying it. At a minimum, the codemeta.json file should include a name, description, a installUrl array containing the NPM URL of the package, and a featureList array.

json { "name": "myplugin", "description": "My awesome plugin", "installUrl": [ "https://www.npmjs.com/package/myplugin", ], "featureList": [ ... ] }

Publish standalone binaries

Not everyone has Node.js installed. To make your plugin available to as many possible users as possible we encourage you to create standalone binaries for major operating systems.

This repo provides an example of how to create standalone binaries for Linux, MacOS and Windows using pkg. These binaries are published for each release with a target triplet name that is suitable for download by Stencila. Check out the build.sh script and the pkg property in the package.json to see how to reuse this approach for your own plugin.

Add the binaries as assets to each release (see how we do this automatically using semantic-release) and add the GitHub releases URL to installUrl so that Stencila knows that standalone binaries are an installation option:

json "installUrl": [ ... "https://github.com/me/myplugin/releases" ]

Publish a Docker image

Some users may prefer to use your plugin as a Docker image.

This repo contains a Dockerfile that shows how you can create a Docker image for your plugin based on the Linux binary. Once it is published add the Docker Hub URL to installUrl so that Stencila knows that is an installation option:

json "installUrl": [ ... "https://hub.docker.com/r/me/myplugin" ]

💬 Tip: Stencila will attempt to install a plugin based on the order of URLs in installUrl. So, for example, if it's best that your users use a Docker image, put it first and that method will be used, if possible, and if the user hasn't specified a installation preference.

🛠️ Develop

Get started by cloning this repository, installing dependencies and running the command line interface:

sh git clone git@github.com:stencila/jesta cd jesta npm install npm start

Please run the formatting, linting and testing scripts when contributing code e.g.

sh npm run format npm run lint npm run test::watch

Alternatively, use make if you prefer,

sh make format lint test

There are also some test fixtures that you can try the CLI out on e.g.

sh npm start -- compile+build+execute tests/fixtures/one/index.json

🙏 Acknowledgements

  • The read method uses got, keyv and content-type to enable cached reads of URLs and determine the format of the returned content.

  • The validate method uses Ajv, "the fastest JSON Schema validator for Node.js and browser", to validate and coerce JSON documents against our schema.

  • The compile method relies on Acorn, a "tiny, fast JavaScript parser, written completely in JavaScript", to determine the imports, declares, uses etc properties of CodeChunk and CodeExpression nodes in documents.

  • The command line interface is implemented using minimist.

Owner

  • Name: Stencila
  • Login: stencila
  • Kind: organization
  • Email: hello@stenci.la

CodeMeta (codemeta.json)

{
  "name": "jesta",
  "softwareVersion": "1.10.2",
  "description": "Stencila plugin for executable documents using JavaScript",
  "installUrl": [
    "https://www.npmjs.com/package/@stencila/jesta",
    "https://github.com/stencila/jesta/releases",
    "https://hub.docker.com/r/stencila/jesta"
  ],
  "featureList": [
    {
      "title": "convert",
      "type": "object",
      "required": [
        "input",
        "output"
      ],
      "properties": {
        "input": {
          "description": "The URL to read content from.",
          "type": "string",
          "pattern": "^(file|https?|stdio|stdin|string)://.*"
        },
        "output": {
          "description": "The URL to write the content to.",
          "type": "string",
          "pattern": "^(file|stdio|stdout|string)://.*"
        },
        "from": {
          "description": "Format to import the document from. Defaults to the file extension (or media type, for remote URLs).",
          "type": "string",
          "enum": [
            "json"
          ]
        },
        "to": {
          "description": "Format to export the documents to. Defaults to the file extension.",
          "type": "string",
          "enum": [
            "json"
          ]
        },
        "cache": {
          "description": "Use and store cached content (for http:// URLs only).",
          "type": "boolean"
        },
        "upcast": {
          "description": "Upcast the document after it is imported?",
          "type": "boolean",
          "const": false
        },
        "downcast": {
          "description": "Downcast the document before it is exported?",
          "type": "boolean",
          "const": false
        },
        "validate": {
          "description": "Validate the document after it is imported?",
          "type": "boolean",
          "const": true
        }
      }
    },
    {
      "title": "decode",
      "description": "Decode content of a specific format into a Stencila node.",
      "required": [
        "content",
        "format"
      ],
      "properties": {
        "content": {
          "description": "The content to be decoded",
          "type": "string"
        },
        "format": {
          "description": "The format to be decoded from",
          "enum": [
            "json"
          ]
        }
      },
      "interruptible": false
    },
    {
      "title": "encode",
      "description": "Encode a Stencila node to content of a specific format.",
      "required": [
        "node",
        "format"
      ],
      "properties": {
        "node": {
          "description": "The node to be encoded"
        },
        "format": {
          "description": "The format to be encoded to",
          "enum": [
            "json"
          ]
        },
        "theme": {
          "description": "The theme for the exported content (only applies to some formats)",
          "type": "string"
        }
      },
      "interruptible": false
    },
    {
      "title": "get",
      "description": "Get a variable from a document.",
      "required": [
        "name"
      ],
      "properties": {
        "name": {
          "description": "The name of the variable.",
          "type": "string"
        }
      }
    },
    {
      "title": "import",
      "description": "Import a document from a URL.",
      "required": [
        "input"
      ],
      "properties": {
        "input": {
          "description": "The URL to read content from.",
          "type": "string",
          "pattern": "^(file|https?|stdio|stdin|string)://.*"
        },
        "format": {
          "description": "Format to import the document from. Defaults to the file extension (or media type, for remote URLs).",
          "type": "string",
          "enum": [
            "json"
          ]
        },
        "cache": {
          "description": "Use and store cached content (for http:// URLs only).",
          "type": "boolean"
        },
        "upcast": {
          "description": "Upcast the document after it is imported?",
          "type": "boolean",
          "const": false
        },
        "validate": {
          "description": "Validate the document after it is imported?",
          "type": "boolean",
          "const": true
        }
      }
    },
    {
      "title": "pull",
      "description": "Pull file/s from a URL to the file system",
      "required": [
        "input",
        "output"
      ],
      "properties": {
        "input": {
          "description": "The URL to fetch.",
          "type": "string",
          "pattern": "^(https?|file|stdio|stdin|string)://.*"
        },
        "output": {
          "description": "The file path to write to",
          "type": "string"
        }
      }
    },
    {
      "title": "read",
      "description": "Read content from a URL.",
      "required": [
        "input"
      ],
      "properties": {
        "input": {
          "description": "The URL to read content from.",
          "type": "string",
          "pattern": "^(file|https?|stdio|stdin|string)://.*"
        },
        "cache": {
          "description": "Use and store cached content (for http:// URLs only).",
          "type": "boolean"
        }
      }
    },
    {
      "title": "select",
      "description": "Select child nodes from a node.",
      "required": [
        "node",
        "query"
      ],
      "properties": {
        "node": {
          "description": "The node to select from."
        },
        "query": {
          "description": "The query to run against the node.",
          "type": "string"
        },
        "lang": {
          "description": "The language that the query is written in.",
          "enum": [
            "simplepath"
          ]
        }
      }
    },
    {
      "title": "set",
      "description": "Set a variable in a document.",
      "required": [
        "name",
        "value"
      ],
      "properties": {
        "name": {
          "description": "The name of the variable to set.",
          "type": "string"
        },
        "value": {
          "description": "The value to to set the variable to."
        }
      }
    },
    {
      "title": "validate",
      "description": "Validate a node against the Stencila Schema.",
      "required": [
        "node"
      ],
      "properties": {
        "node": {
          "description": "The node to validate."
        },
        "force": {
          "description": "Coerce the node to ensure it is valid (e.g. dropping properties)?",
          "type": "boolean",
          "const": true
        }
      }
    },
    {
      "title": "write",
      "description": "Write content to a URL.",
      "required": [
        "content",
        "output"
      ],
      "properties": {
        "content": {
          "description": "The content to write",
          "type": "string"
        },
        "output": {
          "description": "The URL to write the content to.",
          "type": "string",
          "pattern": "^(file|stdio|stdout|string)://.*"
        }
      }
    }
  ]
}

GitHub Events

Total
  • Issues event: 2
  • Issue comment event: 1
  • Push event: 29
Last Year
  • Issues event: 2
  • Issue comment event: 1
  • Push event: 29

Committers

Last synced: 10 months ago

All Time
  • Total Commits: 216
  • Total Committers: 4
  • Avg Commits per committer: 54.0
  • Development Distribution Score (DDS): 0.25
Past Year
  • Commits: 0
  • Committers: 0
  • Avg Commits per committer: 0.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
Nokome Bentley n****e@s****a 162
Renovate Bot b****t@r****m 28
Stencila CI Bot ci@s****a 23
renovate[bot] 2****] 3
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 5 months ago

All Time
  • Total issues: 2
  • Total pull requests: 44
  • Average time to close issues: over 3 years
  • Average time to close pull requests: about 1 month
  • Total issue authors: 1
  • Total pull request authors: 1
  • Average comments per issue: 0.0
  • Average comments per pull request: 1.02
  • Merged pull requests: 30
  • Bot issues: 2
  • Bot pull requests: 44
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • renovate[bot] (2)
Pull Request Authors
  • renovate[bot] (44)
Top Labels
Issue Labels
Pull Request Labels
released (23)

Packages

  • Total packages: 1
  • Total downloads:
    • npm 136 last-month
  • Total dependent packages: 2
  • Total dependent repositories: 5
  • Total versions: 23
  • Total maintainers: 3
npmjs.org: @stencila/jesta

Stencila plugin for executable documents using JavaScript

  • Versions: 23
  • Dependent Packages: 2
  • Dependent Repositories: 5
  • Downloads: 136 Last month
Rankings
Dependent repos count: 5.2%
Downloads: 6.0%
Dependent packages count: 9.0%
Average: 10.6%
Forks count: 15.8%
Stargazers count: 17.2%
Maintainers (3)
Last synced: 5 months ago

Dependencies

package-lock.json npm
  • 837 dependencies
package.json npm
  • @semantic-release/exec 6.0.3 development
  • @stencila/dev-config 3.0.4 development
  • @types/content-type 1.1.5 development
  • @types/estree 0.0.50 development
  • @types/jest 27.5.1 development
  • @types/mime 2.0.3 development
  • @types/parse-author 2.0.1 development
  • @types/parse-full-name 1.2.2 development
  • jest 28.1.0 development
  • json-schema 0.3.0 development
  • mock-stdin 1.0.0 development
  • nock 13.1.1 development
  • pkg 5.3.1 development
  • tempy 3.0.0 development
  • ts-jest 28.0.2 development
  • ts-node 10.2.0 development
  • typedoc 0.21.5 development
  • typescript 4.3.5 development
  • @stencila/logga ^4.0.0
  • acorn ^8.4.0
  • acorn-walk ^8.1.0
  • ajv ^8.6.0
  • ajv-formats ^2.1.0
  • content-type ^1.0.4
  • got ^11.8.2
  • keyv ^4.0.3
  • mime ^2.5.2
  • minimist ^1.2.5
  • parse-author ^2.0.0
  • parse-full-name ^1.2.5
Dockerfile docker
  • ubuntu 20.04 build