memorelay
TypeScript icon, indicating that this package has built-in type declarations

2.0.4 • Public • Published

memorelay

In-memory Nostr relay implementing NIP-01.

Why use memorelay?

This relay implementation has NO persistent storage. When the server is shut down (or crashes) all event data goes with it.

Why would you want a relay with no persistence?

  • For testing (all data is throw-away anyway).
  • For ephemeral communications (persistence is undesirable).
  • For speed (starts up fast, no database/file system lag)

If you need persistence, then you'll probably be happier with a more full-featured relay implementation like nostream.

Installing and Running

Local install:

npm install memorelay

Run locally through npx:

npx memorelay

Alternative global install:

npm install --global memorelay

If installed globally, call memorelay directly:

memorelay

To stop the server from running, type Ctrl-C to send an interrupt signal to the process.

Command-line Options

To see the memorelay command options, invoke it with the --help flag:

$ npx memorelay --help
Usage: memorelay [options]

In-memory Nostr relay.

Options:
  -V, --version            output the version number
  -p, --port <number>      TCP port on which to listen (default: "3000")
  -l, --log-level <level>  Minimum log level to report (default: "info")
  -h, --help               display help for command

Using with Node.js HTTP Server

To use memorelay in your TypeScript project with Node's built-in HTTP server:

import { Memorelay } from 'memorelay';

const memorelay = new Memorelay().connect();
const httpServer = createServer(memorelay.handleRequest());
httpServer.on('upgrade', memorelay.handleUpgrade());
httpServer.listen({ port: 3000 });

Note: the .connect() call is mandatory. Without that, your memorelay instance won't listen for any events. This is to give your plugins a chance to attach listeners first.

Using with Express

To use memorelay in your TypeScript project with an Express server:

import { Memorelay } from 'memorelay';

const memorelay = new Memorelay().connect();
const app = express();
app.use('/', memorelay.handleRequest());
const server = app.listen(3000);
server.on('upgrade', memorelay.handleUpgrade());

Note: the .connect() call is mandatory. Without that, your memorelay instance won't listen for any events. This is to give your plugins a chance to attach listeners first.

Using plugins

Behaviors in memorelay are implemented through an event-based, plugin API. A memorelay plugin is a function which attaches event listeners.

Plugin should be generally be added to the constructor, or at least attach their listeners before you call .connect(). This way, plugins' event listeners are earlier in the stack and will have a chance to call events' .preventDefault() methods to stop other functionality if desired.

Example that adds the plugin to the constructor:

import { examplePluginFn } from './example-plugin.ts';

const memorelay = new Memorelay(examplePluginFn).connect();

Example that adds listeners before calling .connect():

import { examplePluginFn } from './example-plugin.ts';

const memorelay = new Memorelay();

examplePluginFn(memorelay);

memorelay.connect();

The advantage to providing the plugin functions to the constructor is that they'll be automatically removed if you call the memorelay's .disconnect() method. Using the later example above, the example plugin's listeners would still be attached, even after disconnect.

Developing

To develop, start by forking the repo, then check out your fork locally. From there, you can run the development server, run tests, lint, build and package the code.

Conventions

This is an opinionated codebase. To wit:

The purpose of all this automation and specification is to reduce the likelihood of errors. More about each of these in the sections that follow.

Environment

Visual Studio Code is the recommended IDE for this project because it understands TypeScript by default and offers plugins which can aid conformance to conventions.

Recommended plugins:

  • ESLint - Checks for ESLint errors.
  • Prettier - Applies code formatting on save.

Having said that, you're welcomed to use whatever IDE or programming environment you like.

Running a Dev Server

Next, run npm clean-install to download all dependencies.

To run locally, you have two options:

  • npm start - Uses ts-node to run the current code once.
  • npm run start:dev - Uses nodemon to watch for code changes and restart the server automatically.

Since memorelay has no persistence, every time it restarts it will forget all events it had learned. For that reason you may prefer the former, as it will not restart automatically.

Testing

To run unit tests, you have two options:

  • npm test - Run jest unit tests once.
  • npm run test:dev - Run tests continuously, rerunning with each code change.

Since unit tests are stateless, the later invocation is typically preferred.

Linting

This project uses ESLint to enforce code style. To run:

npm run lint

If there are no lint errors, the command will produce no output.

If a word is misspelled, you'll see a Warning. If the word is spelled correctly, but is still identified as a misspelling, then you can add the word to the skipWords constant at the head of the .eslintrc file:

const skipWords = `
dotenv ecma fileoverview fs lang jsx memorelay microtask msg nostr printf pubkey
readonly req sig tsconfig tsx unparseable utf ws wss
`.match(/\w+/g);

Code Style

This project defines and checks code style with Prettier. To run the prettier checks, use npm run prettier. This will show which files, if any, have style violations.

Check Licenses

Source code for memorelay is released under the Apache 2.0 license. Each source code file MUST include an SPDX license header like this:

/**
 * @license SPDX-License-Identifier: Apache-2.0
 */

To check whether all source files have such a header, run npm run check-licenses. The output will tell you if there are any files missing the header.

Building

Currently, building only means generating the TypeScript definition files from the source code (see issue #7).

Nevertheless, you can run the TypeScript compiler (tsc) via the command npm run build.

Packaging

In some cases, you may need to test the behavior of the packaged binary.

First, run npm run package. This will update the files under ./dist/bin. Then you can run the distributable binary with this command:

node ./dist/bin/index.js

Note: DO NOT commit your updated dist files. These will be updated automatically by semantic-release.

Committing

Commits to the memorelay codebase should follow the conventional commits format:

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

The <type> should be one of the types specified by the Angular Commit Message Format:

  • build: Changes that affect the build system or external dependencies.
  • ci: Changes to our CI configuration files and scripts (semantic-release, GitHub Actions).
  • docs: Documentation only changes.
  • feat: A new feature.
  • fix: A bug fix.
  • perf: A code change that improves performance.
  • refactor: A code change that neither fixes a bug nor adds a feature.
  • test: Adding missing tests or correcting existing tests.

The <description> should be a sentence describing the change (capitalized first word, trailing punctuation).

For example, if you fixed a bug in the way reaction events are handled, your commit message might look like this:

git commit -m "fix: Corrected reaction event handling (kind=6)."

Our release process uses these commit messages to determine the next version number and to automatically generate the release CHANGELOG.md file. So it's important that your commit messages are clear and meaningful.

Continuous Integration and Release

This project uses semantic-release to automate releases based on commits. The Release workflow (release.yml) is invoked by GitHub Actions whenever code is pushed to the main branch.

Pushing to the main branch should only be done by pull request, OR by semantic-release's automated commits. Pull requests should be merged normally and NOT squashed.

In addition to the Release workflow, there's a Dev workflow (dev.yml). It performs all the same steps--running tests, build, linter, etc.--except that it does not push to npm.

Using semantic-release to push code back to GitHub and deliverables to npm requires authentication tokens. These tokens may have expiration dates, and so it's possible for the automated releases to fail due to token expiration.

You can find the token menu under Settings -> Security -> Secrets and variables -> Actions.

LICENSE

Source code is released under the Apache 2.0 license.

Readme

Keywords

Package Sidebar

Install

npm i memorelay

Weekly Downloads

1

Version

2.0.4

License

Apache-2.0

Unpacked Size

2.1 MB

Total Files

630

Last publish

Collaborators

  • jimbojw