No description
Find a file
Dirk Hoyer 2fe82af259 fix: Update URLs to use correct ixtaat.com domains
- Replace docs.ixt.dev with www.ixtaat.com
- Fix 'GitHub:' label to 'Repository:' for Forgejo URL

Part of comprehensive URL standardization across IXT codebase.
2025-11-02 16:08:15 +01:00
examples Initial commit 2025-10-15 08:57:01 +02:00
.gitignore Initial commit 2025-10-15 08:57:01 +02:00
BIDIRECTIONAL_IPC_GUIDE.md Initial commit 2025-10-15 08:57:01 +02:00
CHANGELOG.md Initial commit 2025-10-15 08:57:01 +02:00
IMPLEMENTATION_SUMMARY.md Initial commit 2025-10-15 08:57:01 +02:00
ixt-process-module.js Initial commit 2025-10-15 08:57:01 +02:00
LICENSE feat(sdk-nodejs): Add MIT license for SDK distribution 2025-10-23 08:38:54 +02:00
package.json fix: Update URLs to use correct ixtaat.com domains 2025-11-02 16:08:15 +01:00
PYTHON_TO_NODEJS.md Initial commit 2025-10-15 08:57:01 +02:00
QUICKREF.md Initial commit 2025-10-15 08:57:01 +02:00
README.md fix: Update URLs to use correct ixtaat.com domains 2025-11-02 16:08:15 +01:00
RELEASE_NOTES.md fix: Update URLs to use correct ixtaat.com domains 2025-11-02 16:08:15 +01:00
test-services.js Initial commit 2025-10-15 08:57:01 +02:00

IXT Node.js SDK

Node.js SDK for building IXT modules that run as separate processes and communicate with the IXT runtime via IPC.

Features

  • Simple base class for module development
  • Automatic IPC connection handling
  • JSON message parsing and framing
  • Lifecycle management (init, handle, shutdown, health_check)
  • Base64 payload encoding/decoding helpers
  • Error handling and logging
  • Zero external dependencies (Node.js 14+)
  • Full async/await support
  • NEW: Bidirectional IPC Services
    • MessageBus: Send messages to other modules
    • KV Store: Persist and retrieve data (get, set, delete, exists)
    • Logging: Send structured logs to runtime

Installation

# From source
cd sdk/ixt-sdk-nodejs
npm install

# Or copy ixt-process-module.js to your project
cp sdk/ixt-sdk-nodejs/ixt-process-module.js my-module/

Quick Start

1. Create Your Module

#!/usr/bin/env node
const { IxtProcessModule } = require('./ixt-process-module');

class MyModule extends IxtProcessModule {
  async onInit(config) {
    // Initialize module with configuration
    this.dbUrl = config.database_url || 'sqlite://data.db';
    this.log(`Connecting to database: ${this.dbUrl}`);
    // Initialize your resources here
  }

  async onHandle(message, context) {
    // Handle incoming messages
    const topic = message.topic;
    const payloadData = this.decodePayload(message.payload);
    
    if (topic === 'my.service.process') {
      const result = await this.processData(payloadData);
      return this.success({
        result: this.encodePayload(result)
      });
    } else if (topic === 'my.service.query') {
      const data = await this.queryData(payloadData);
      return this.success({
        data: this.encodePayload(data)
      });
    } else {
      return this.error('UNKNOWN_TOPIC', `Unknown topic: ${topic}`);
    }
  }

  async onShutdown() {
    // Clean up resources
    this.log('Shutting down module');
    // Close connections, save state, etc.
  }

  async onHealthCheck() {
    // Report health status (optional)
    return {
      healthy: true,
      database_connected: await this.checkDbConnection(),
      requests_processed: this.requestCount
    };
  }
}

if (require.main === module) {
  new MyModule().run();
}

2. Create Manifest

# manifest.toml
schema_version = "3.0"

[module]
name = "my-module"
version = "1.0.0"
description = "My IXT module"
author = "Your Name"
license = "MIT"
runtime_targets = ["Process"]

[provides]
services = ["my.service.process", "my.service.query"]

[config]
database_url = { type = "string", default = "sqlite://data.db" }

3. Run Your Module

The IXT runtime will spawn your module automatically. For development testing:

# Runtime sets these environment variables:
export IXT_IPC_SOCKET=/tmp/ixt-module-abc123.sock
export IXT_MODULE_ID=my-module:1.0.0/instance-001

# Run your module
node my-module.js

API Reference

IxtProcessModule Base Class

Abstract base class for IXT modules. Implement these methods:

onInit(config)

Initialize your module with configuration from the manifest.

async onInit(config) {
  this.setting = config.my_setting || 'default';
  // Initialize resources, connect to services, etc.
}

onHandle(message, context)

Handle incoming messages. This is where your business logic goes.

async onHandle(message, context) {
  const topic = message.topic;
  const payload = this.decodePayload(message.payload);
  
  // Process the message
  const result = await this.process(payload);
  
  // Return success or error
  return this.success({ result: this.encodePayload(result) });
}

Message structure:

{
  topic: 'service.name',           // Service topic
  payload: 'base64-encoded-data',  // Base64-encoded payload
  priority: 1,                     // Priority level
  ttl_ms: 5000                     // Time-to-live in milliseconds
}

Context structure:

{
  trace_id: 'unique-trace-id',     // Distributed tracing ID
  source_module: 'caller:1.0.0',   // Calling module
  timestamp: 1234567890            // Unix timestamp
}

onShutdown()

Gracefully shutdown your module.

async onShutdown() {
  await this.db.close();
  await this.saveState();
}

onHealthCheck() (optional)

Report health status. Default returns {healthy: true}.

async onHealthCheck() {
  return {
    healthy: await this.isHealthy(),
    uptime_seconds: process.uptime()
  };
}

Helper Methods

success(data)

Create a success response.

return this.success({ result: 42 });

error(code, message, details)

Create an error response.

return this.error('INVALID_INPUT', 'Missing required field: name');

encodePayload(data)

Encode binary data as base64 string.

const encoded = this.encodePayload(Buffer.from("hello world"));

decodePayload(payload)

Decode base64 payload to Buffer.

const data = this.decodePayload(message.payload);
const text = data.toString('utf8');

log(message)

Log informational message (to stderr, captured by runtime).

this.log(`Processing request ${requestId}`);

logError(message)

Log error message.

this.logError(`Failed to connect: ${error}`);

Bidirectional IPC Services

The SDK provides methods to interact with runtime services from within your module.

MessageBus Service

Send messages to other modules via the MessageBus.

sendMessage(topic, payload, priority, ttlMs)

Send a message to another module.

const response = await this.sendMessage(
  'notifications.send',                    // Topic
  Buffer.from(JSON.stringify({             // Payload (binary)
    user_id: 123,
    message: 'Hello!'
  })),
  2,                                       // Priority: 1=low, 2=normal, 3=high, 4=critical
  5000                                     // TTL in milliseconds (optional)
);

if (response.success) {
  this.log('Message sent successfully');
}

Parameters:

  • topic (string): Message topic (e.g., "user.created", "order.process")
  • payload (Buffer): Binary message payload
  • priority (number): Message priority (1=low, 2=normal, 3=high, 4=critical), default: 1
  • ttlMs (number, optional): Time-to-live in milliseconds

Returns: Promise