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

@tauri-liesel/reg

v0.1.5

Published

[![npm version](https://img.shields.io/npm/v/@tauri-liesel/reg.svg)](https://www.npmjs.com/package/@tauri-liesel/reg) [![Crates.io](https://img.shields.io/crates/v/tauri-plugin-reg.svg)](https://crates.io/crates/tauri-plugin-reg) [![License: MIT](https://

Downloads

56

Readme

@tauri-liesel/reg

npm version Crates.io License: MIT Tauri v2

A Tauri v2 plugin that provides a typed, file-system-backed Node Registry for desktop applications. It scans a local nodes/ directory for JSON node definitions and exposes them to your frontend via a strongly-typed IPC API, enabling dynamic, data-driven node-graph UIs with full TypeScript support.


✨ Features

  • 🗂 File-system node discovery — Automatically scans and loads all .json node definitions from a nodes/ directory at runtime.
  • 🔌 Seamless Tauri IPC — Bridges Rust and JavaScript via Tauri's invoke mechanism under the plugin:reg|* namespace.
  • 🦀 Robust Rust deserialization — Custom Serde logic gracefully handles mixed-type JSON fields (strings, numbers, booleans, single objects vs. arrays), making it tolerant of loosely-typed node files.
  • 🧩 In-memory NodeRegistry singleton — A ready-to-use TypeScript class that acts as an in-memory store: register nodes, look them up by Identifier, and iterate over all loaded definitions.
  • 📐 Fully typed API — Complete TypeScript types for NodeData, NodePort, WireConnection, DataType, PortType, and Identifier.
  • 🛡 Tauri capability-based permissions — Fine-grained allow/deny permission identifiers for every exposed command (reg:allow-load-lsnodes, reg:allow-ping).
  • 🖥 Desktop & Mobile — Conditional compilation targets for both desktop (direct file I/O) and mobile (delegated to native Android/iOS plugin handles).
  • 📦 Dual ESM + CJS build — Ships both ES Module (.js) and CommonJS (.cjs) bundles with bundled TypeScript declarations (.d.ts).
  • ⚡ Zero UI dependencies — Pure data layer; no UI framework assumptions. Works with React, Svelte, Vue, or vanilla JS.

📦 Installation

1. Install the JavaScript package

npm install @tauri-liesel/reg
# or
pnpm add @tauri-liesel/reg
# or
yarn add @tauri-liesel/reg
# or
bun add @tauri-liesel/reg

2. Add the Rust plugin to your Tauri application

In your Tauri app's src-tauri/Cargo.toml, add:

[dependencies]
tauri-plugin-reg = "0.1.5"

Local workspace path (if using from source):

tauri-plugin-reg = { path = "../path/to/tauri-liesel/reg" }

3. Register the plugin in Rust

In src-tauri/src/lib.rs:

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_reg::init())
        // ... other plugins
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

4. Grant permissions in your Tauri capability

In src-tauri/capabilities/default.json:

{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "description": "Default capability for the application",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "reg:default",
    "reg:allow-load-lsnodes"
  ]
}

🚀 Quick Start

Setting up the node directory

Create a nodes/ directory alongside your Tauri application binary. Each .json file in this directory describes one node definition:

my-tauri-app/
├── nodes/
│   ├── prompt_builder.json
│   ├── image_input.json
│   └── llm_output.json
└── src-tauri/
    └── ...

Example node definition (nodes/prompt_builder.json):

{
  "id": "core:prompt-builder",
  "title": "Prompt Builder",
  "subtitle": "Constructs an LLM prompt",
  "x": 0,
  "y": 0,
  "selected": false,
  "headerPreset": "llm",
  "nodeType": "promptBuilder",
  "icon": "📝",
  "inputs": [
    {
      "id": "in_text",
      "name": "Text",
      "type": "input",
      "dataType": "string",
      "enabled": true
    }
  ],
  "outputs": [
    {
      "id": "out_prompt",
      "name": "Prompt",
      "type": "output",
      "dataType": "string",
      "enabled": true
    }
  ]
}

Using the NodeRegistry in your frontend

import { NodeRegistry } from '@tauri-liesel/reg';

// Load all node definitions from the file system (calls Rust via IPC)
await NodeRegistry.loadFromDisk();

// Get all registered node definitions
const allNodes = NodeRegistry.values();
console.log(allNodes); // NodeData[]

// Look up a specific node by its Identifier ('namespace:name')
const node = NodeRegistry.get('core:prompt-builder');
console.log(node.title); // "Prompt Builder"

Registering nodes manually

You can also register node definitions programmatically at runtime:

import { NodeRegistry } from '@tauri-liesel/reg';
import type { NodeData } from '@tauri-liesel/reg';

const myNode: NodeData = {
  id: 'custom:my-node',
  title: 'My Custom Node',
  x: 100,
  y: 200,
  selected: false,
  nodeType: 'custom',
  icon: '⭐',
  inputs: [],
  outputs: [],
};

NodeRegistry.register(myNode);

📖 API Reference

JavaScript / TypeScript

NodeRegistry (singleton)

The exported NodeRegistry is a pre-instantiated singleton of the internal NodeReg class.

| Method | Signature | Description | |--------|-----------|-------------| | register | (node: NodeData) => void | Adds or overwrites a node in the in-memory registry by its id. | | get | (id: Identifier) => NodeData | Retrieves a node by its Identifier. Returns a sentinel "Missing Node" if not found. | | values | () => NodeData[] | Returns an array of all currently registered NodeData objects. | | loadFromDisk | () => Promise<void> | Invokes the plugin:reg|load_lsnodes Tauri command to load .json node files from the nodes/ directory and registers them all. Errors are silently swallowed. |


TypeScript Types

Identifier

A branded template literal type for namespaced node IDs.

type Identifier = `${string}:${string}`;
// e.g. 'core:prompt-builder', 'custom:my-node'

PortType

type PortType = 'input' | 'output';

DataType

type DataType =
  | 'string'
  | 'float'
  | 'vector3'
  | 'color'
  | 'texture'
  | 'exec'
  | 'bool'
  | 'mask';

NodePort

Describes a single input or output socket on a node.

interface NodePort {
  id: string;
  name: string;
  type: PortType;
  dataType?: DataType;
  enabled: boolean;
  color?: string;     // Custom socket ring color (CSS color string)
  value?: string;     // Optional default value
}

NodeData

The primary node definition shape.

interface NodeData {
  id: Identifier;
  title: string;
  subtitle?: string;
  x: number;
  y: number;
  selected: boolean;
  headerPreset?: 'llm' | 'subject' | 'style' | 'setting' | 'lighting' | 'camera' | 'parameters' | 'special';
  customHeaderGradient?: string;
  inputs: NodePort[];
  outputs: NodePort[];
  width?: number;
  nodeType: string;
  icon: string;
}

WireConnection

Represents a directed connection between two node ports.

interface WireConnection {
  id: string;
  fromNodeId: string;
  fromPortId: string;
  toNodeId: string;
  toPortId: string;
  color?: string;
}

Tauri IPC Commands

These commands are invoked internally by the JS API but can also be called directly via @tauri-apps/api's invoke.

| Command | IPC Call | Description | Returns | |---------|----------|-------------|---------| | load_lsnodes | plugin:reg\|load_lsnodes | Reads all .json files from the nodes/ directory relative to the app's working directory and deserializes them into NodeDataDef structs. | NodeDataDef[] | | ping | plugin:reg\|ping | Diagnostic echo command. Returns the same value that was sent. | PingResponse |


Rust API

The plugin exposes a Ext trait implemented for tauri::App, tauri::AppHandle, and tauri::Window, providing access to the underlying Reg instance:

use tauri_plugin_reg::Ext;

// Inside a Tauri command or event handler:
fn my_command(app: tauri::AppHandle) {
    let reg = app.reg(); // -> &Reg<R>
    let response = reg.ping(PingRequest { value: Some("hello".into()) });
}

🔐 Permissions Reference

All permissions follow Tauri v2's capability-based security model with the reg: prefix.

| Permission Identifier | Description | |-----------------------|-------------| | reg:default | Grants the default permission set (currently includes allow-ping). | | reg:allow-ping | Allows the ping command. | | reg:deny-ping | Denies the ping command. | | reg:allow-load-lsnodes | Allows the load_lsnodes command (required for NodeRegistry.loadFromDisk()). | | reg:deny-load-lsnodes | Denies the load_lsnodes command. |

Note: reg:allow-load-lsnodes is not included in reg:default. You must explicitly grant it in your capability configuration.


🏗 Build System

| Asset | Tool | Output | |-------|------|--------| | JavaScript (ESM) | Rollup + @rollup/plugin-typescript | dist-js/index.js | | JavaScript (CJS) | Rollup | dist-js/index.cjs | | TypeScript declarations | tsc (via Rollup plugin) | dist-js/index.d.ts | | Rust library | cargo build | target/ | | Plugin permissions | tauri-plugin build script | permissions/autogenerated/ |

Build the JavaScript bundle:

npm run build
# or
pnpm build

🧱 Project Structure

tauri-liesel/reg/
├── guest-js/               # TypeScript source (compiled to dist-js/)
│   ├── index.ts            # NodeRegistry class + all type exports
│   └── types.ts            # Standalone type definitions
├── src/                    # Rust plugin source
│   ├── lib.rs              # Plugin init, Ext trait, command handler registration
│   ├── commands.rs         # Tauri command implementations (ping, load_lsnodes)
│   ├── models.rs           # Shared Rust models (PingRequest, PingResponse)
│   ├── error.rs            # Plugin error enum + Serialize impl
│   ├── desktop.rs          # Desktop-specific Reg struct (direct file I/O)
│   └── mobile.rs           # Mobile-specific Reg struct (Android/iOS plugin handle)
├── permissions/
│   ├── default.toml        # Default permission set definition
│   └── autogenerated/      # Auto-generated per-command allow/deny TOMLs
├── examples/
│   └── tauri-app/          # Svelte + Tauri v2 reference application
├── dist-js/                # Compiled JS/TS output (not checked in)
├── build.rs                # Rust build script (registers commands for tauri-plugin)
├── Cargo.toml              # Rust crate metadata
├── package.json            # npm package metadata
├── rollup.config.js        # Rollup build configuration
└── tsconfig.json           # TypeScript compiler options

🔧 Serde Deserialization Details

The Rust side employs custom deserializers in commands.rs to tolerate loosely-typed legacy JSON node files:

| Deserializer | Handles | |---|---| | deserialize_bool_from_string | true/false as native booleans or "true"/"false" strings | | deserialize_number_from_string | Numbers as native JSON numbers or numeric strings | | deserialize_opt_number_from_string | Optional numbers; also strips trailing "px" suffixes | | deserialize_vec_or_single | Port arrays that may be a single object {} instead of [{}] |

This means your nodes/*.json files are resilient to minor type inconsistencies without causing a load failure.


🛠 Development & Contributing

# Clone the repository
git clone https://github.com/valeArt/tauri-liesel

# Navigate to the plugin directory
cd tauri-liesel/reg

# Install JS dependencies
pnpm install

# Build the JS bundle
pnpm build

# Run the example application
cd examples/tauri-app
pnpm install
pnpm tauri dev

📋 Requirements

| Requirement | Minimum Version | |-------------|----------------| | Tauri | ^2.11.3 | | @tauri-apps/api (JS peer) | ^2.0.0 | | Rust | 1.77.2 | | Node.js | >=18 (LTS recommended) |


📄 License

MIT © ValeArt