Skip to content

Latest commit

 

History

History
219 lines (152 loc) · 7.94 KB

CONTRIBUTING.md

File metadata and controls

219 lines (152 loc) · 7.94 KB

Setup

This build uses node version 18.15.0. We use Yarn instead of npm to help us better manage dependencies from TensorFlow.js. Yarn is a newer package manager that is very similar to NPM. Here is a cheat sheet for npm vs Yarn commands.

Install nvm and run the following commands:

nvm install 18.15
nvm use 18
npm install -g yarn

To start the development server, run the following commands:

yarn
yarn start

You should see something similar to this in the terminal:

[webpack-dev-server] Project is running at:
[webpack-dev-server] Loopback: http://localhost:8080/
...
...
webpack 5.76.1 compiled successfully in 8360 ms

A local server have been started and hosts a built version of the ml5 library at http://localhost:8080/dist/ml5.js. While the server is running, Webpack will automatically rebuild the library if you change and save any file in the /src folder.

A webpage at http://localhost:8080/examples/ should automatically open with the directory listing of the example directory. Select one of the directories to test run ml5.js in some example code.

Code Formatting

To keep the coding style consistent, we will be using the Prettier formatter.

Visual Studio Code

If you are using Visual Studio Code, you can install the Prettier extension by going to the Extensions tab and search for "Prettier". Click on Prettier - Code formatter and click Install.

Go to File > Preferences > Settings, search for "default formatter" and make sure Prettier - Code formatter is selected for Editor: Default Formatter.

To automatically format a document when saving it, search for "format on save" in the settings and make sure Editor: Format On Save is checked. Otherwise, you can use the VS Code keyboard shortcut to format an opened document, which is shift + alt + f for Windows or shift + option + f for Mac by default.

Command Line

You can also format a document via the command line. To format all JavaScript documents in the repo, use:

yarn run format

To format a specific document, use

npx prettier --write path/to/file

For more options with the command line, refer to the Prettier Documentation

Building the Library

To build the ml5 library for production, run the following commands

yarn
yarn run build

This will create a production version of the library in /dist directory.

Making Releases

This section is a temporary guide for contributors who wants to make a alpha release manually.

  1. Create a new pull request on the main branch to update the SemVer number in package.json. For alpha releases, simply increment the trailing number in the SemVer. For example, "version": "0.20.0-alpha.3" should be changed to "version": "0.20.0-alpha.4".

  2. Merge the pull request.

  3. Switch to the main branch and make sure the code is up to date by running the following command:

git checkout main
git pull
  1. Make sure all dependencies have been installed by running the following command:
yarn
  1. Build the project with the following command and wait for the build to complete:
yarn run build
  1. Run the following command and log in with an npm account that has write access to the ml5 package. You may be redirected to a browser window for authentication.
npm login
  1. Publish the package with the following command. You may be redirected to a browser window for authentication.
npm publish --tag alpha --access public
  1. The package should now be available at. (Replace [version] with the new SemVer set in step 1).
   https://unpkg.com/ml5@[version]/dist/ml5.js

All Contributors

If you contributed to the project in any way, we would like to include you in our contributors list in README.md.

To add a new contributor, create a new branch from main. Then, enter the following command in the terminal:

yarn all-contributors add

Complete the prompts in the terminal.

Make a pull request to merge the new branch into main. When the branch gets merged, the new contributor will show up in README.md!

Utils

This section documents the utility functions found in the src/utils folder.

handleOptions is a function that filters a user defined options object based on rules in a mold object, returning a filtered options object. The function logs friendly warnings in the console when one of the user defined options violates the rules.

const filteredOptions = handleOptions(userObject, moldObject);

userObject

The userObject is an object defined by the user to configure the options of a model. For example, the below object configures the handpose model to detect a maximum of 4 hands using the "full" variant:

const optionsObject = {
  maxHands: 4,
  modelType: full,
};

moldObject

Inspired by Mongoose Models, the moldObject defines how the userObject should be filtered. Here is an example optionsObject:

const mold = {
  maxHands: {
    type: "number",
    min: 1,
    default: 2,
  },
  runtime: {
    type: "enum",
    enums: ["mediapipe", "tfjs"],
    default: "mediapipe",
  },
  modelType: {
    type: "enum",
    enums: ["lite", "full"],
    default: "full",
  },
};

This particular moldObject allows the user to have a maxHands option with a minimum value of 1, a runtime option with the value of either mediapipe or tfjs, and a modelType option with the value of either lite or full.

Define a Rule in moldObject

The moldObject consists of key-value pairs. The key defines the name of an allowed option, and the value is an object that contains rules on how the option should be filtered. Here are the rules:

  • type (required): A string defining the correct type, can be "number", "enum", "boolean", "string", "object", or "undefined".
  • default (required): The default value in case the user does not provide a value or provides an erroneous value for the option.
  • ignore (optional): A boolean defining whether the key should be ignored. Defaults to false. Useful when set to a dynamically evaluated value (see section below).
  • Specifically for type: "number":
    • min (optional): A number defining the minimum value.
    • max (optional): A number defining the maximum value.
    • integer (optional): A boolean defining whether the value should be an integer. Defaults to false.
    • multipleOf (optional): A number. When defined, the user value must be a multiple of this number.
  • Specifically for type: "enum":
    • enums (required): An array defining a list of valid values.
    • caseInsensitive (optional): A boolean defining whether to checks the user value against the enum list case-insensitively. Defaults to true.

Functions As Rules

A rule can be a constant value or a function that is dynamically evaluated. The function will be called with the current filtered object as its parameter. Below is an example usage:

const mold = {
  runtime: {
    type: "enum",
    enums: ["mediapipe", "tfjs"],
    default: "mediapipe",
  },
  maxHands: {
    type: "number",
    min: 1,
    default: (filteredObject) => filteredObject.runtime === "mediapipe" ? 4 : 2;
  },
};

When the user sets the runtime to mediapipe, the default value of maxHands is 4, and when the user sets the runtime to tfjs, the default maxHands is 2.

Caveat: the options gets processed from top to bottom in the order defined in the moldObject, and the filteredObject only contains the options that has already been processed. Thus, runtime must be placed above maxHands in the moldObject for the function to work properly.