npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@nodius/server

v1.0.1

Published

[![npm version](https://img.shields.io/npm/v/@nodius/server)](https://www.npmjs.com/package/@nodius/server) [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue)](https://www.typescriptlang.org/) [![License: ISC](https://img.shields.io/badge/

Readme

@nodius/server

npm version TypeScript License: ISC

Backend API and WebSocket server for Nodius. This package provides the complete cloud infrastructure for executing graphical workflows with real-time multi-user support.

Table of Contents

Installation

In the Monorepo

npm install

As Standalone Package

npm install @nodius/server

Prerequisites

  • Node.js: Version 18+
  • ArangoDB: Version 3.11+ (see installation in root README)
  • Operating System: Windows, macOS, or Linux

Quick Start

Minimal Configuration

# Start ArangoDB (if not already running)
arangod

# From packages/server folder
npm run dev

The server starts on:

  • HTTP/HTTPS: https://localhost:8426
  • WebSocket: wss://localhost:10426
  • Cluster Manager: Port 9426 (internal)

Custom Configuration

# With CLI arguments
npm run dev -- port=3000 host=0.0.0.0 https=true

# With custom certificates
npm run dev -- https=true cert=./path/to/cert.pem key=./path/to/key.pem

# With custom database
npm run dev -- arangodb=http://db-server:8529 arangodb_name=my_nodius_db arangodb_user=admin arangodb_pass=secret

Verify Server is Running

# Check server health
curl https://localhost:8426/api/health

# Should return:
# {"status":"ok","timestamp":1234567890}

Architecture

Nodius server is built on several key components:

┌─────────────────────────────────────────────────────┐
│                  Nodius Server                      │
├─────────────────────────────────────────────────────┤
│                                                     │
│  ┌──────────────────┐      ┌──────────────────┐   │
│  │   HttpServer     │      │  WebSocket       │   │
│  │   (REST API)     │      │  Manager         │   │
│  │                  │      │  (Real-time)     │   │
│  └────────┬─────────┘      └─────────┬────────┘   │
│           │                          │            │
│           │                          │            │
│  ┌────────▼──────────────────────────▼────────┐   │
│  │         Request Handlers                   │   │
│  │  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐     │   │
│  │  │Workflow│ │Category│ │Sync │ │Auth│     │   │
│  │  └──────┘ └──────┘ └──────┘ └──────┘     │   │
│  └────────────────────┬────────────────────── │   │
│                       │                           │
│  ┌────────────────────▼──────────────────────┐   │
│  │         Auth Manager                      │   │
│  │  - JWT Tokens                             │   │
│  │  - Pluggable Providers                    │   │
│  │  - bcrypt Hashing                         │   │
│  └────────────────────┬──────────────────────┘   │
│                       │                           │
│  ┌────────────────────▼──────────────────────┐   │
│  │         ArangoDB Connection               │   │
│  │  - Graph database                         │   │
│  │  - Collections: nodes, edges, workflows   │   │
│  └────────────────────┬──────────────────────┘   │
│                       │                           │
│  ┌────────────────────▼──────────────────────┐   │
│  │       Cluster Manager (ZeroMQ)            │   │
│  │  - Pub/Sub for broadcasts                 │   │
│  │  - Router/Dealer for coordination         │   │
│  └───────────────────────────────────────────┘   │
│                                                     │
└─────────────────────────────────────────────────────┘

Data Flow

  1. HTTP Client → HttpServer → Request Handler → ArangoDB
  2. WebSocket Client → WebSocket Manager → Validation → Broadcast to all clients
  3. Sync Instructions → Validation → Application → Save (auto-save)
  4. Cluster Events → ZeroMQ Pub/Sub → All cluster servers

Main Components

HttpServer

Custom HTTP server with Express-like support for routing and middlewares.

Features

  • Express-like API: Routes with get(), post(), put(), delete()
  • Middlewares: CORS, logging, rate limiting, error handling
  • Body Parsing: Automatic JSON and text parsing
  • File Upload: Multipart/form-data support with Sharp for images
  • Static Files: Serve static files
  • HTTPS: SSL support with automatic self-signed certificate generation
  • Route Parameters: Parameter extraction (/api/workflow/:id)
  • Query Strings: Automatic parsing

Usage

import { HttpServer, cors, logger } from '@nodius/server';

const app = new HttpServer();

// Middlewares
app.use(logger());
app.use(cors());

// Routes
app.get('/api/hello', (req, res) => {
  res.json({ message: 'Hello World' });
});

app.post('/api/data', async (req, res) => {
  const data = req.body;
  // Process data
  res.json({ success: true, data });
});

// Route parameters
app.get('/api/workflow/:id', (req, res) => {
  const workflowId = req.params?.id;
  res.json({ workflowId });
});

// Start server
app.listen({
  port: 8426,
  host: '0.0.0.0',
  https: {
    key: certKey,
    cert: certFile
  }
});

Available Middlewares

// CORS
app.use(cors({
  origin: '*',
  methods: 'GET,POST,PUT,DELETE,OPTIONS',
  allowedHeaders: 'Content-Type,Authorization'
}));

// Logger
app.use(logger());

// Rate limiting
app.use(rateLimit({
  windowMs: 60000,  // 1 minute
  max: 100          // 100 requests per window
}));

// Static files
app.use(staticFiles('./public'));

// Auth middleware (provided by AuthManager)
app.use(authManager.authMiddleware());

WebSocket Manager

WebSocket connection manager for real-time collaboration.

Features

  • Real-time Synchronization: Broadcast instructions to all connected clients
  • Sessions per Workflow: Manage user sessions per workflow
  • Auto-Save: Automatic save every 30 seconds with diff computation
  • Instruction Validation: Consistency checking before application
  • Reconnection: Automatic reconnection support
  • Broadcasting: Selective broadcast per workflow

Architecture

import { WebSocketManager } from '@nodius/server';
import { Database } from 'arangojs';

const db = new Database(/* config */);
const wsManager = new WebSocketManager(db, httpServer);

WebSocket Protocol

Connection Message
{
  "type": "connect",
  "workflowKey": "workflow_123",
  "token": "jwt_token_here"
}
Instructions Message
{
  "type": "instructions",
  "workflowKey": "workflow_123",
  "instructions": [
    {
      "o": 1,
      "p": ["nodes", "node_1", "posX"],
      "v": 100
    }
  ],
  "clientId": "client_abc",
  "timestamp": 1234567890
}
Broadcast Message (server → clients)
{
  "type": "update",
  "workflowKey": "workflow_123",
  "instructions": [...],
  "sourceClientId": "client_abc"
}

Auto-Save Operation

The WebSocket Manager:

  1. Receives instructions from client
  2. Validates and applies instructions in memory
  3. Broadcasts to other connected clients
  4. Every 30 seconds:
    • Compares in-memory state with ArangoDB
    • Calculates diff (missing instructions)
    • Saves only changes
// Auto-save configuration
const AUTO_SAVE_INTERVAL = 30000; // 30 seconds

// System automatically handles:
// - Change detection
// - Diff calculation
// - Batch saving
// - Error handling

Cluster Manager

Distributed cluster manager using ZeroMQ for server coordination.

Features

  • Pub/Sub Pattern: Event broadcasting between servers
  • Router/Dealer Pattern: Point-to-point communication
  • Discovery: Automatic peer discovery
  • Health Checks: Node health monitoring
  • Message Routing: Intelligent message routing

Architecture

Server 1 (Port 9426)          Server 2 (Port 9427)
     │                              │
     │  ┌─────────────────────┐    │
     └──┤  ZeroMQ Pub/Sub     ├────┘
        └─────────────────────┘
              │       │
              ▼       ▼
         Broadcast  Subscribe

Usage

import { ClusterManager } from '@nodius/server';

const clusterManager = new ClusterManager({
  pubPort: 9426,
  subPort: 9427,
  routerPort: 9428,
  dealerPort: 9429
});

// Publish message
clusterManager.publish('workflow.update', {
  workflowKey: 'workflow_123',
  data: { ... }
});

// Subscribe to topic
clusterManager.subscribe('workflow.update', (message) => {
  console.log('Received update:', message);
});

Auth Manager

JWT authentication system with pluggable providers.

Features

  • JWT Tokens: Token generation and validation
  • bcrypt Hashing: Secure password hashing
  • Pluggable Providers: Customizable provider system
  • Default Provider: Default provider with database users
  • Middleware: Automatic route protection
  • Refresh Tokens: Token refresh support

Usage

Initialization
import { AuthManager } from '@nodius/server';
import { Database } from 'arangojs';

const db = new Database(/* config */);
const authManager = AuthManager.getInstance();

await authManager.initialize(db, 'your-jwt-secret');
Create Admin
# Via CLI
npm run create-admin

# Or programmatically
import { createAdmin } from '@nodius/server';
await createAdmin(db, 'admin', 'secure_password');
Protect Routes
// All /api/* routes are automatically protected
// except /api/auth/*

app.use(authManager.authMiddleware());

// Protected route
app.get('/api/protected', (req, res) => {
  const userId = req.user?.id;  // Injected by middleware
  res.json({ userId });
});
Custom Auth Provider
import { AuthProvider, AuthManager } from '@nodius/server';

class MyCustomAuthProvider implements AuthProvider {
  async authenticate(username: string, password: string): Promise<{ id: string; username: string } | null> {
    // Your authentication logic
    // Ex: LDAP, OAuth, etc.
    return { id: 'user_123', username };
  }

  async getUserById(id: string): Promise<{ id: string; username: string } | null> {
    // Get user by ID
    return { id, username: 'user' };
  }
}

// Use custom provider
const authManager = AuthManager.getInstance();
authManager.setProvider(new MyCustomAuthProvider());

API Endpoints

Authentication

POST /api/auth/login

Authenticate a user and obtain a JWT token.

Request:

{
  "username": "admin",
  "password": "secure_password"
}

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "user": {
    "id": "user_123",
    "username": "admin"
  }
}

POST /api/auth/refresh

Refresh an expired token.

Request:

{
  "token": "eyJhbGciOiJIUzI1NiIs..."
}

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIs..."
}

Workflows

GET /api/workflow

List all workflows.

Query params:

  • category (optional): Filter by category
  • limit (optional): Number of results
  • offset (optional): Pagination

Response:

{
  "workflows": [
    {
      "_key": "workflow_123",
      "name": "My Workflow",
      "category": "automation",
      "createdAt": 1234567890,
      "updatedAt": 1234567890
    }
  ],
  "total": 1
}

GET /api/workflow/:key

Get a specific workflow with all its nodes and edges.

Response:

{
  "workflow": {
    "_key": "workflow_123",
    "name": "My Workflow",
    "nodes": [...],
    "edges": [...]
  }
}

POST /api/workflow

Create a new workflow.

Request:

{
  "name": "New Workflow",
  "category": "automation"
}

Response:

{
  "workflowKey": "workflow_456"
}

PUT /api/workflow/:key

Update a workflow.

Request:

{
  "name": "Updated Name",
  "category": "new_category"
}

DELETE /api/workflow/:key

Delete a workflow.

Categories

GET /api/category

List all categories.

POST /api/category

Create a new category.

Request:

{
  "name": "automation",
  "description": "Automation workflows"
}

Node Configurations

GET /api/nodeconfig

List all node configurations.

POST /api/nodeconfig

Create a new node configuration.

Request:

{
  "type": "textNode",
  "name": "Text Node",
  "process": "await next('0', incoming?.data);",
  "version": 1
}

Data Types

GET /api/datatype

List all data types.

POST /api/datatype

Create a new data type.

Images

POST /api/image/upload

Upload an image.

Request: multipart/form-data

  • file: Image file
  • name (optional): Image name

Response:

{
  "imageKey": "image_123",
  "url": "/api/image/image_123"
}

GET /api/image/:key

Get an image (public endpoint, no auth required).

GET /api/image

List all images.

DELETE /api/image/:key

Delete an image.

PUT /api/image/:key/rename

Rename an image.

Request:

{
  "name": "new_name.png"
}

History

GET /api/history/:workflowKey

Get modification history for a workflow.

Response:

{
  "history": [
    {
      "timestamp": 1234567890,
      "instructions": [...],
      "userId": "user_123"
    }
  ]
}

Configuration

Environment Variables

The server can be configured via CLI arguments or environment variables:

| CLI Argument | Env Variable | Default | Description | |-------------|--------------|---------|-------------| | port | PORT | 8426 | HTTP/HTTPS port | | host | HOST | localhost | Server host | | https | HTTPS | false | Enable HTTPS | | cert | SSL_CERT | - | SSL certificate path | | key | SSL_KEY | - | SSL key path | | arangodb | ARANGO_URL | http://127.0.0.1:8529 | ArangoDB URL | | arangodb_user | ARANGO_USER | root | ArangoDB user | | arangodb_pass | ARANGO_PASS | azerty | ArangoDB password | | arangodb_name | ARANGO_DB | nodius | Database name | | jwt_secret | JWT_SECRET | (generated) | Secret for JWT tokens |

Startup Example

# Local development
node dist/server.js

# Production with HTTPS and custom DB
node dist/server.js \
  port=443 \
  host=0.0.0.0 \
  https=true \
  cert=/etc/ssl/cert.pem \
  key=/etc/ssl/key.pem \
  arangodb=https://db.example.com:8529 \
  arangodb_user=nodius \
  arangodb_pass=secure_pass \
  jwt_secret=my_super_secret_key

CLI Tools

The server package includes several CLI tools:

Create Admin

Create an administrator user:

npm run create-admin

# Or with tsx
npx tsx src/cli/createAdmin.ts

Export Data

Export all workflows and configurations:

npx tsx src/cli/export.ts output.json

Import Data

Import workflows from a file:

npx tsx src/cli/import.ts input.json

Development

Package Structure

packages/server/
├── src/
│   ├── auth/                    # Authentication system
│   │   ├── AuthManager.ts       # Main manager
│   │   ├── AuthProvider.ts      # Provider interface
│   │   └── DefaultAuthProvider.ts
│   ├── cli/                     # CLI tools
│   │   ├── createAdmin.ts
│   │   ├── export.ts
│   │   └── import.ts
│   ├── cluster/                 # Distributed cluster
│   │   ├── clusterManager.ts    # ZeroMQ cluster
│   │   └── webSocketManager.ts  # WebSocket server
│   ├── http/                    # HTTP server
│   │   └── HttpServer.ts        # Custom implementation
│   ├── request/                 # Request handlers
│   │   ├── requestAuth.ts
│   │   ├── requestWorkFlow.ts
│   │   ├── requestCategory.ts
│   │   ├── requestDataType.ts
│   │   ├── requestNodeConfig.ts
│   │   ├── requestSync.ts
│   │   ├── requestHistory.ts
│   │   └── requestImage.ts
│   ├── utils/                   # Utilities
│   │   ├── arangoUtils.ts
│   │   ├── env.ts
│   │   ├── generateCert.ts
│   │   └── image/
│   │       ├── imageCompression.ts
│   │       └── imageValidation.ts
│   ├── server.ts                # Main entry point
│   └── index.ts                 # Exports
├── certs/                       # Generated SSL certificates
├── package.json
├── tsconfig.json
└── README.md

Development Scripts

# Start in development mode
npm run dev

# Build package
npm run build

# Generate barrel files
npm run barrelize

# Create admin
npm run create-admin

Adding a New Endpoint

  1. Create a file in src/request/:
// src/request/requestMyFeature.ts
import { HttpServer } from '../http/HttpServer';
import { db } from '../server';

export class RequestMyFeature {
  static init(app: HttpServer) {
    app.get('/api/myfeature', async (req, res) => {
      // Your logic
      res.json({ data: 'Hello' });
    });

    app.post('/api/myfeature', async (req, res) => {
      const data = req.body;
      // Process data
      res.json({ success: true });
    });
  }
}
  1. Register in server.ts:
import { RequestMyFeature } from './request/requestMyFeature';

// After app initialization
RequestMyFeature.init(app);
  1. Export in index.ts:
export * from './request/requestMyFeature';

Deployment

Deployment with PM2

# Install PM2
npm install -g pm2

# Start server
pm2 start dist/server.js --name nodius-server -- port=8426 https=true

# View logs
pm2 logs nodius-server

# Restart
pm2 restart nodius-server

# Stop
pm2 stop nodius-server

Deployment with Docker

FROM node:18-alpine

WORKDIR /app

# Copy files
COPY package*.json ./
COPY packages/server ./packages/server
COPY packages/utils ./packages/utils
COPY packages/process ./packages/process

# Install and build
RUN npm install
RUN npm run build

# Expose ports
EXPOSE 8426 9426 10426

# Environment variables
ENV PORT=8426
ENV HTTPS=true
ENV ARANGO_URL=http://arangodb:8529

# Start
CMD ["node", "packages/server/dist/server.js"]

Deployment with Systemd

# /etc/systemd/system/nodius-server.service
[Unit]
Description=Nodius Server
After=network.target arangodb.service

[Service]
Type=simple
User=nodius
WorkingDirectory=/opt/nodius
ExecStart=/usr/bin/node /opt/nodius/packages/server/dist/server.js port=8426 https=true
Restart=on-failure
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=nodius-server

Environment=NODE_ENV=production
Environment=ARANGO_URL=http://localhost:8529
Environment=ARANGO_USER=nodius
Environment=ARANGO_PASS=secure_password

[Install]
WantedBy=multi-user.target
# Enable and start
sudo systemctl enable nodius-server
sudo systemctl start nodius-server

# View logs
sudo journalctl -u nodius-server -f

Cluster Deployment

To deploy multiple instances in cluster:

  1. Configure ZeroMQ on each server
  2. Share the same ArangoDB database
  3. Load Balancer in front of instances (nginx, HAProxy)
# nginx configuration for load balancing
upstream nodius_backend {
    server server1.example.com:8426;
    server server2.example.com:8426;
    server server3.example.com:8426;
}

server {
    listen 443 ssl http2;
    server_name nodius.example.com;

    ssl_certificate /etc/ssl/cert.pem;
    ssl_certificate_key /etc/ssl/key.pem;

    location /api {
        proxy_pass https://nodius_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    location /ws {
        proxy_pass https://nodius_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
    }
}

Security

Best Practices

  1. JWT Secret: Use a strong and unique secret
  2. HTTPS: Always enable HTTPS in production
  3. Rate Limiting: Configure appropriate limits
  4. CORS: Restrict allowed origins
  5. Validation: Validate all user inputs
  6. ArangoDB: Use strong credentials
  7. Updates: Keep dependencies up to date

Secure Configuration Example

// Strict rate limiting
app.use(rateLimit({
  windowMs: 60000,  // 1 minute
  max: 30          // 30 requests max
}));

// Restricted CORS
app.use(cors({
  origin: 'https://your-domain.com',
  methods: 'GET,POST,PUT,DELETE',
  allowedHeaders: 'Content-Type,Authorization'
}));

// Strong JWT secret
const jwtSecret = process.env.JWT_SECRET || crypto.randomBytes(64).toString('hex');

Contributing

Contributions are welcome! To contribute:

  1. Respect the modular architecture
  2. Add tests if applicable
  3. Document new endpoints
  4. Maintain compatibility with existing clients

Support

  • Issues: https://github.com/Nodius-kit/Nodius/issues
  • API Documentation: See types in @nodius/utils

License

ISC - See LICENSE


Creator

Hugo MATHIEU


Note: This server is designed to be deployed in a secure cloud environment. Make sure to follow security best practices in production.