Skip to content

gbmhunter/NinjaTerm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The NinjaTerm logo.

A serial port terminal that's got your back.



Build Status Github Tag

Install

If you want to use NinjaTerm, visit the NinjaTerm homepage to download the desktop application or use the older web-based version (the web-based version is no longer being updated).

From the homepage there are also links to the NinjaTerm manual.

You can also access older versions of NinjaTerm at GitHub Releases.

The rest of this README is for developers who want to contribute to NinjaTerm.

Directory Structure

Below is the directory structure of this repository:

ninjaterm/
├── arduino-serial/ # Contains Arduino sketches for testing the serial port
├── docs/ # Contains Docusaurus website which contains the homepage, installation guide and manual. Self-contained node project.
├── src/ # Contains the Electron application code.
├── tests/ # Contains the end-to-end tests using Playwright.
├── web/ # Contains the web-based version of NinjaTerm. Self-contained node project.

Development

Clone this repo. Then run npm install to install dependencies:

npm install

Start electron for development:

npm run dev

To Build The App

npm run build

Testing

Both unit tests and end-to-end tests can be run with:

npm run test

Unit Tests

Unit tests are run with vitest, which has good integration with Vite.

To run just the unit tests, use the command:

npx vitest run

E2E Tests

End-to-end (E2E) (a.k.a. integration tests) are performed using Playwright. The Playwright tests are located in the tests/ directory, and the Playwright config is at playwright.config.ts.

To run just the E2E tests from command line:

npx playwright test

The Playwright plug-in for VS Code is recommended if interacting with these tests, as it makes running and debugging of them easy!

Real Tests With An Arduino

Arduino sketches in arduino-serial allow you to program different applications onto an Arduino for testing the serial port with.

Releasing

  1. Create a new branch off of main for the changes.
  2. Make changes to the code as required.
  3. Update the version number to the appropriate number in package.json. Major version number change for big changes (e.g. framework change or compete overhaul of UI). Minor version change when additional features have been added. Patch version change for bug fixes and small changes to existing functionality.
  4. Update the CHANGELOG (don't forget the links right at the bottom of the page).
  5. If you have updated the app data structure, save a copy of the default app data created by the app to local-storage-data/. You can do this by running the app, clearing app data in Settings > General Settings, loading up the Chrome dev. tools, and copying the key appData from local storage.
  6. Commit changes and push to your feature/bug fix branch.
  7. Create pull request on GitHub merging your branch into main.
  8. Once the build on main has been successfully run, merge your branch into main via the merge request.
  9. Tag the branch on main with the version number, e.g. v4.1.0.
  10. Create a release on GitHub pointing to the tag.
  11. Enter the CHANGELOG contents into the release body text.

Deployment

Netlify is used to deploy and host the static NinjaTerm HTML/JS. Netlify automatically deploys when the main branch is updated. Netlify also creates preview deploys on pull requests (link will be automatically posted into the PR comments).

Web App

NinjaTerm used to be a progressive web app (PWA). This older web app is now located in the web directory. The web directory is a project in it's own right, see it's README.md for more details.

This is no longer being updated and is in maintenance mode only.

The web app is deployed by Netlify to ninjaterm-app.mbedded.ninja.

styled_default is not a function

If you get the following error in the web app:

Grid2.js:7 Uncaught TypeError: styled_default is not a function
    at Grid2.js:7:26

Comment out the line:

include: ['@mui/material/Tooltip', '@emotion/styled', '@mui/material/Unstable_Grid2'],

in vite.config.ts. This should fix it. You can then uncomment the line again. Toggling this seems to fix this bug, which after reading online might be due to Vite.

Graphing

Both recharts and chart.js was trialed for graphing data coming in on a serial port.

chart.js was chosen as it offered much better performance when the data update rate was fast. rechart could handle about 100 points, any more than that at the render time per new point started to take more than 50ms. chart.js can re-render 1000 points and stay under that limit.

Performance

NinjaTerm can easily handle 50kB/s of incoming serial data when maximized on a 1920x1080 screen. Reported "CPU usage" inside the app (busy time of the main javascript event loop) is around 50% when this is happening on my machine.

Make sure that often updating React components are in their own MobX observers. Prior to doing this, I had things like the throughput, CPU usage, and TX/RX activity bulbs (all in the bottom status bar) directly in the main AppView component. This causes the entire app to re-render when any of these values change, at caused noticeable performance problems at 10kB/s.

Fonts

FontCreator was used to create the special NinjaTerm font. It is based of Consolas. The FontCreator project file is at src/fonts/NinjaTerm.fcp and the generated font files are NinjaTerm-Regular.woff and NinjaTerm-Regular.woff2.

The PUA (Personal Use Area) is used to add custom glyphs to represent control characters and generic hex bytes. The following code point ranges are used:

  • U+E000 - U+E07F: Contains control character glyphs were applicable. Add 0xE000 to a byte which contains a control character to get the equivalent glyph.
  • U+E100 - U+E1FF: Contains a glyph for each byte from 0x00 to 0xFF containing the byte as a hex number. For example, U+E100 contains a glyph that says 00, and U+E1FF contains a glyph that says FF. Add 0xE100 to a normal byte to get the corresponding glyph.

In FontCreator, make sure the setting Tools->Options->Fonts->Exclude unused glyphs is unchecked, otherwise glyphs at code points like 0x0001 will not be generated.

Theme Colors

  • #DC3545 (red): Primary colour, used for logo.
  • #E47F37 (orange): Secondary colour, used for buttons on homepage.

Saving App Data

Settings are stored to the browser's local storage. The app data is saved under the key appData. The AppDataManager class is responsible for loading the data, updating it to the latest version if out of date, and saving it back to local storage.

The folder local-storage-data/ contains some example app data files for different versions of the app.

The files with default in the name are the default data for that app version. These are used in the unit tests to make sure upgrading app data works correctly.

Extensions

  • Prettier ESLint: Provides formatting of .tsx files.
  • Playwright: Provides useful add-ons for running and debugging the Playwright E2E tests.