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

@ternion/opc-link-client

v0.1.2

Published

A lightweight TypeScript client library for interacting with the TERNION-OPC-REST-API

Readme

@ternion/opc-link-client

A lightweight TypeScript client library for interacting with the QNetLinks OPC REST API. This library provides a type-safe interface for reading and writing OPC UA node values through a RESTful API.

Features

  • Fully type-safe API client with comprehensive TypeScript support and proper return types
  • Class-based API with TernionOpcLinkClient for easy instantiation
  • Read operations: Query cached values, read specific nodes, and retrieve aliases with typed responses
  • Write operations: Write Boolean, Int16, and Float values to OPC nodes
  • Alias support: Convenient access to predefined alias channels (bool, int16, float)
  • Convenience methods: Helper methods for reading channels and vectors with proper typing
  • Error handling: Comprehensive error handling with descriptive messages
  • ESM modules: Modern ES module syntax with native Node.js support
  • Zero dependencies: Uses native fetch API (Node.js 18+)

Prerequisites

  • Node.js 18+ (required for native fetch API)
  • QNetLinks OPC REST API running at http://localhost:9990 (default, configurable)

Installation

npm install @ternion/opc-link-client

Quick Start

import { TernionOpcLinkClient } from '@ternion/opc-link-client';

// Create a client instance (uses default URL: http://localhost:9990/opc/api/v1)
const client = new TernionOpcLinkClient();

// Or specify a custom API URL
const client = new TernionOpcLinkClient('http://your-api-host:port/opc/api/v1');

// Get API information
const info = await client.getApiInfo();
console.log(info);

// Check API health
const health = await client.getHealth();
console.log(health);

Usage

Basic Example

import { TernionOpcLinkClient } from '@ternion/opc-link-client';

const client = new TernionOpcLinkClient();

// Get all cached values
const values = await client.getValues();
console.log(values);

Reading Values

import { TernionOpcLinkClient } from '@ternion/opc-link-client';

const client = new TernionOpcLinkClient();

// Read a specific node by ID
const value = await client.getValue('ns=1;s=Boolean.0');

// Read by alias (channel 0 of bool type)
const aliasValue = await client.getAlias('bool', 0);

// Get all aliases of a type
const allBools = await client.getAllAliases('bool');

// Force a fresh read (bypass cache)
const freshValue = await client.readNode({ 
  nodeId: 'ns=1;s=Boolean.0', 
  forceRefresh: true 
});

Writing Values

import { TernionOpcLinkClient } from '@ternion/opc-link-client';

const client = new TernionOpcLinkClient();

// Write using convenience helpers
await client.writeBoolean(0, true);        // Write to Boolean.0
await client.writeInt16(1, 42);            // Write to Int16.1
await client.writeFloat(2, 3.14159);       // Write to Float.2

// Write using generic writeNode method
await client.writeNode({
  nodeId: 'ns=1;s=CustomNode',
  dataType: 'Boolean',
  value: true,
  refreshCache: true
});

Error Handling

All methods throw errors on failure. Always wrap calls in try-catch:

try {
  await client.writeBoolean(0, true);
} catch (error) {
  console.error('Write failed:', error);
  // Handle error appropriately
}

API Reference

TernionOpcLinkClient Class

Constructor

new TernionOpcLinkClient(apiBaseUrl?: string)

Creates a new client instance. The apiBaseUrl parameter is optional and defaults to "http://localhost:9990/opc/api/v1".

Methods

Information & Health
  • getApiInfo(): Promise<ApiInfo> - Get API metadata and available endpoints
  • getHealth(): Promise<HealthStatus> - Get current health status of the bridge
Reading Values
  • getValues(): Promise<NodeValue[]> - Get all cached node values
  • getValue(nodeId: string): Promise<NodeValue> - Get cached value for a specific node
  • getAlias(type: AliasType, channel: number): Promise<NodeValue> - Get value by alias and channel
  • getAllAliases(type: AliasType): Promise<AliasCollection> - Get all channels for an alias type
  • readNode(request: ReadRequest): Promise<NodeValue> - Read a node (optionally force refresh)
  • readBoolean(channel: number, forceRefresh?: boolean): Promise<NodeValue> - Read Boolean channel
  • readInt16(channel: number, forceRefresh?: boolean): Promise<NodeValue> - Read Int16 channel
  • readFloat(channel: number, forceRefresh?: boolean): Promise<NodeValue> - Read Float channel
  • readBooleanVector(forceRefresh?: boolean): Promise<NodeValue> - Read BooleanVector node
  • readInt16Vector(forceRefresh?: boolean): Promise<NodeValue> - Read Int16Vector node
  • readFloatVector(forceRefresh?: boolean): Promise<NodeValue> - Read FloatVector node
Writing Values
  • writeNode(request: WriteRequest): Promise<WriteResponse> - Generic write function
  • writeBoolean(channel: number, data: boolean): Promise<WriteResponse> - Write boolean value
  • writeInt16(channel: number, data: number): Promise<WriteResponse> - Write 16-bit integer (-32768 to 32767)
  • writeFloat(channel: number, data: number): Promise<WriteResponse> - Write floating-point value
Static Validation Methods
  • TernionOpcLinkClient.validateChannel(channel: number): void - Validate channel index
  • TernionOpcLinkClient.validateAliasType(type: string): asserts type is AliasType - Validate alias type

Types

AliasType

type AliasType = 'bool' | 'int16' | 'float';

ReadRequest

interface ReadRequest {
  nodeId: string;
  forceRefresh?: boolean;
}

WriteRequest

interface WriteRequest {
  nodeId: string;
  dataType: 'Boolean' | 'Int16' | 'Float' | string | number;
  value: unknown;
  arrayType?: string | number;
  refreshCache?: boolean;
}

WriteResponse

interface WriteResponse {
  status: string;
  nodeId: string;
  result: NodeValue;
}

NodeValue

interface NodeValue {
  nodeId: string;
  value: unknown;
  dataType: string;
  arrayType: string;
  statusCode: string;
  sourceTimestamp: string;
  serverTimestamp: string;
  updatedAt: string;
}

ApiInfo

interface ApiInfo {
  [key: string]: unknown;
}

API metadata information returned by the root endpoint.

HealthStatus

interface HealthStatus {
  [key: string]: unknown;
}

Health status information returned by the health endpoint.

AliasCollection

type AliasCollection = NodeValue[];

Collection of alias values returned by getAllAliases().

Examples

See the examples/ directory for complete usage examples.

Run the demo example:

npm start

Or directly:

npx tsx examples/demo.ts

Development

Building

npm run build

This compiles TypeScript to the dist/ directory.

Type Checking

npx tsc --noEmit

Cleaning

npm run clean

Removes the dist/ directory.

Project Structure

@ternion/opc-link-client/
├── src/
│   ├── index.ts                  # Main entry point
│   └── ternion-opc-link-client/
│       └── ternion-opc-link-client.ts  # Client implementation
├── dist/                         # Compiled output (generated)
├── examples/                     # Example code
│   └── demo.ts
├── package.json
├── tsconfig.json
└── README.md

License

MIT

Changelog

[Unreleased]

Improved

  • Type Safety: Replaced all Promise<unknown> return types with proper TypeScript interfaces
    • getApiInfo() now returns Promise<ApiInfo>
    • getHealth() now returns Promise<HealthStatus>
    • getValues() now returns Promise<NodeValue[]>
    • getValue(), getAlias(), readNode(), and all convenience read methods now return Promise<NodeValue>
    • getAllAliases() now returns Promise<AliasCollection>
  • Added new exported types: ApiInfo, HealthStatus, and AliasCollection
  • Enhanced type safety throughout the library for better IDE autocomplete and compile-time error checking