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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@hyfy/jsclient

v4.0.2

Published

This is the JS client for custom server-side access of R1 Edge Node fleets

Downloads

554

Readme

@hyfy/jsclient

JavaScript/TypeScript SDK for interacting with the NaeuralEdgeProtocol network.

This repository contains the runtime client, node/pipeline management API, blockchain helper utilities, schemas, tests, and generated typings used by the published npm package.

What This SDK Does

  • Connects to Naeural MQTT topics for heartbeats, payloads, and notifications.
  • Verifies/signs messages through NaeuralBC.
  • Tracks network state (in-memory or Redis-backed).
  • Exposes high-level node operations through NodeManager (pipeline and plugin lifecycle).
  • Publishes batched node configuration changes through explicit commit() operations.

Installation

npm install @hyfy/jsclient

Runtime Requirements

  • Node.js 20+ recommended (CI uses Node 20).
  • Access to an MQTT broker for Naeural network topics.
  • Optional Redis when using REDIS_STATE_MANAGER.

Public API (Top-Level Exports)

From @hyfy/jsclient:

  • Naeural, NaeuralEvent, NaeuralEventType
  • NodeManager, Pipeline, PluginInstance
  • NaeuralBC
  • all constants from src/constants.js (for example ALL_EDGE_NODES, INTERNAL_STATE_MANAGER, REDIS_STATE_MANAGER)
  • DCT constants/schemas from src/utils/dcts
  • convertKeysToCamelFormat, convertKeysToNaeuralFormat

Quick Start

import {
  Naeural,
  NaeuralEvent,
  NaeuralEventType,
  ALL_EDGE_NODES,
  INTERNAL_STATE_MANAGER
} from '@hyfy/jsclient';

const client = new Naeural({
  initiator: 'my-app',
  stateManager: INTERNAL_STATE_MANAGER,
  mqttOptions: {
    url: 'mqtt://<broker-host>:1883',
    username: '<username>',
    password: '<password>',
    clean: true,
    clientId: 'client-01',
    prefix: 'jsclient'
  },
  blockchain: {
    key: process.env.NAEURAL_PRIVATE_KEY_DER_HEX ?? '',
    encrypt: true,
    secure: true,
    debug: false
  },
  threads: {
    heartbeats: 1,
    notifications: 1,
    payloads: 1
  },
  fleet: [ALL_EDGE_NODES]
});

client.on(NaeuralEvent.NAEURAL_CLIENT_BOOTED, () => {
  console.log('Client booted:', client.getName());
  console.log('Blockchain address:', client.getBlockChainAddress());
});

client.getStream(NaeuralEventType.HEARTBEAT)?.subscribe(({ context, data, error }) => {
  if (error) {
    return;
  }
  console.log('Heartbeat from:', context?.address);
});

client.boot();

Main Mechanics

1) Boot Sequence

client.boot():

  • spawns/starts worker threads for heartbeat, notification, and payload streams
  • connects the main MQTT client
  • emits lifecycle events (including boot success and blockchain address)
  • starts memory usage aggregation across main thread + workers

2) State Management Modes

  • INTERNAL_STATE_MANAGER (default): single-process state.
  • REDIS_STATE_MANAGER: shared state/event routing across processes via Redis pub/sub.

If Redis mode is used, configure:

{
  stateManager: REDIS_STATE_MANAGER,
  redis: {
    host: 'localhost',
    port: 6379,
    password: null
  }
}

3) Fleet Filtering

  • fleet: [ALL_EDGE_NODES] processes all observed nodes.
  • fleet: ['<node-name-or-address>', ...] restricts processing to selected nodes.
  • registerEdgeNode() / deregisterEdgeNode() can adjust fleet membership at runtime.

Comms Diagnostics (NET_MON Investigation)

The client now emits low-noise comms diagnostics from both worker threads and the main thread.

Configuration flags:

{
  commsDiagnostics: {
    enabled: true,      // default true
    windowMs: 60000,    // default 60s summaries
    netMonSampleRate: 10 // worker-side NET_MON trace sampling (every 10th)
  }
}

Worker log prefix:

  • [COMMS][JSCLIENT][thread=<id>][type=<threadType>]

Main-thread log prefix:

  • [COMMS][JSCLIENT][main][initiator=<initiator>]

What is counted in worker summaries:

  • stage counters: MQTT receive, buffer->string, signature gate, JSON parse, edge-node gate, fleet gate, formatter gate, decode
  • side-path counters: supervisorAdminSeen, supervisorNetMonSeen
  • routing counters: postedToMainByType, postedToRedisByType
  • drop reasons: signature_invalid, signature_exception, parse_error, fleet_filtered, unknown_formatter, decode_exception, plus additional gate reasons

NET_MON sampled traces include only safe identifiers:

  • EE_SENDER
  • EE_PAYLOAD_PATH head/signature
  • EE_MESSAGE_ID, EE_MESSAGE_SEQ
  • local per-message seq for stage correlation

No payload/body secrets are printed by diagnostics paths.

Quick interpretation for a 3-minute investigation window:

  1. Check worker mqttMessageReceived and NET_MON trace lines to confirm NET_MON reached the MQTT thread.
  2. Compare pass/drop counters and dropReasons to identify the exact gate where loss occurs.
  3. Check funnelException and funnelException stage=... logs for stream failures; bad messages are dropped, not fatal.
  4. Check main-thread workerMessagesByType, streamEventsByType, emittedEventsByType, and threadBoot logs to validate boot/subscription health and downstream emissions.

Node Operations With NodeManager

NodeManager is retrieved from a running client:

const manager = await client.getNodeManager('<node-name-or-address>');
if (!manager) {
  throw new Error('Node not available in fleet/universe yet.');
}

Typical flow:

  1. createPipeline(...) or getPipeline(...)
  2. create/update plugin instances
  3. call commit() to publish network commands

Example:

import { DCT_TYPE_VIDEO_STREAM } from '@hyfy/jsclient';

const pipeline = await manager.createPipeline(
  {
    type: DCT_TYPE_VIDEO_STREAM,
    config: {
      URL: 'rtsp://example.local/stream',
      CAP_RESOLUTION: 20
    }
  },
  'camera-pipeline'
);

await manager.prepareCustomCode(
  "plugin.int_cache['runs'] = (plugin.int_cache.get('runs') || 0) + 1",
  'custom-exec-instance',
  pipeline
);

await manager.commit();

Schemas and Extensibility

Built-in DCT schemas are preloaded (VideoStream, VideoFile, MetaStream, Void, OnDemand*).

Plugin schemas are registry-driven:

  • default plugin schema included: CUSTOM_EXEC_01
  • for other plugin signatures, register schemas before creating instances
client.registerPluginSchema('MY_PLUGIN_SIGNATURE', mySchema);

Blockchain / Identity

NaeuralBC handles:

  • key generation/loading
  • message signing and verification
  • payload encryption/decryption
  • address derivation

CLI key generation:

npx @hyfy/jsclient generate ./identity.json

This command prints and optionally writes:

  • DER private/public key data
  • PEM private key
  • derived Naeural address (0xai_...)

Treat private keys as secrets.

Events and Streams

Event constants are exposed via NaeuralEvent, for example:

  • NAEURAL_CLIENT_BOOTED
  • NAEURAL_BC_ADDRESS
  • NAEURAL_ENGINE_REGISTERED
  • NAEURAL_ENGINE_DEREGISTERED
  • NAEURAL_ENGINE_OFFLINE

Stream constants via NaeuralEventType:

  • HEARTBEAT
  • PAYLOAD
  • NOTIFICATION

Use client.getStream(type) for observable streams and client.on(event, handler) for EventEmitter events.

Development

npm install
npm test
npm run test:coverage
npm run lint
npm run format
npm run generate:typedefs

Documentation Artifacts

  • Generated API markdown: API.md
  • Generated JSDoc output: docs/jsdoc/
  • TypeScript declarations: types/

CI / Release Workflow

Current workflow file: .github/workflows/release.yml

It currently:

  • installs dependencies
  • runs tests with coverage
  • uploads coverage to Codecov
  • creates a GitHub release on version change

It does not currently publish to npm.

License

Apache-2.0. See LICENSE.