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

@obinexusltd/obix-adapter

v0.1.0

Published

OBIX DP Adapter - data-oriented paradigm translation layer

Readme

@obinexusltd/obix-adapter

The Data-Oriented Programming (DOP) paradigm translation layer for OBIX. This package enables seamless conversion between programming paradigms: data-oriented ↔ functional ↔ OOP ↔ reactive.

Overview

The OBIX Adapter pattern solves a fundamental problem in modern software: different teams, libraries, and frameworks prefer different programming paradigms. The DP Adapter enables a single component definition to work across all these paradigms without duplication or loss of functionality.

Paradigm Support

  • Data-Oriented (DO): Pure data representation as the canonical source
  • Functional (FP): Closure-based stateful functions
  • Object-Oriented (OOP): Class-based components with bound methods
  • Reactive (RX): Observable pattern with subscriptions and notifications

Installation

npm install @obinexusltd/obix-adapter

Quick Start

import { DOPAdapter, Paradigm } from "@obinexusltd/obix-adapter";

// 1. Define your component in data-oriented form
const counterLogic = {
  name: "Counter",
  state: { count: 0 },
  actions: {
    increment: ({ state }) => {
      state.count += 1;
    },
    decrement: ({ state }) => {
      state.count -= 1;
    },
  },
  render: ({ state }) => ({
    text: `Count: ${state.count}`,
    value: state.count,
  }),
};

// 2. Create an adapter
const adapter = new DOPAdapter(counterLogic);

// 3. Transform to any paradigm

// Functional
const FunctionalComponent = adapter.toFunctional();
const result = FunctionalComponent(); // { text: "Count: 0", value: 0 }

// OOP
const OOPClass = adapter.toOOP();
const instance = new OOPClass();
instance.increment();
instance.render(); // { text: "Count: 1", value: 1 }

// Reactive
const reactiveComponent = adapter.toReactive();
reactiveComponent.subscribe((state) => {
  console.log("State changed:", state);
});
reactiveComponent.dispatch("increment");

// Generic
const result = adapter.transform(Paradigm.REACTIVE);

API Reference

DOPAdapter<S>

The main adapter class for paradigm transformations.

Constructor

new DOPAdapter(logic: ComponentLogic<S>)

Creates an adapter from component logic.

Methods

toFunctional(): FunctionalComponent<S>

Transforms the component to a functional paradigm using closures.

const adapter = new DOPAdapter(logic);
const FunctionalComponent = adapter.toFunctional();
const output = FunctionalComponent();

Characteristics:

  • Returns a function that encapsulates state in closures
  • State is local to each function invocation
  • Actions are curried functions within the closure
toOOP(): OOPComponentClass<S>

Transforms the component to an OOP paradigm with class-based instance.

const adapter = new DOPAdapter(logic);
const MyClass = adapter.toOOP();
const instance = new MyClass();
instance.state;      // { count: 0 }
instance.increment(); // executes action
instance.render();    // returns rendered output

Characteristics:

  • Returns a class constructor
  • Actions become bound instance methods
  • State is a property on the instance
  • Mutable state that persists across method calls
toReactive(): ReactiveComponent<S>

Transforms the component to a reactive paradigm with observable pattern.

const adapter = new DOPAdapter(logic);
const reactive = adapter.toReactive();

const unsubscribe = reactive.subscribe((state) => {
  console.log("Updated state:", state);
});

reactive.dispatch("increment"); // triggers notification
unsubscribe(); // stop listening

Characteristics:

  • Returns a component with subscribe/notify pattern
  • Actions trigger automatic state notifications
  • Multiple subscribers supported
  • Change detection for state mutations
toDataOriented(): ComponentLogic<S>

Returns a normalized data-oriented representation (identity transform).

const adapter = new DOPAdapter(logic);
const normalizedLogic = adapter.toDataOriented();
// Returns a fresh copy of the component logic
transform(target: Paradigm): TransformResult<S>

Generic transformation dispatcher that routes to the appropriate method.

const result = adapter.transform(Paradigm.REACTIVE);
// result.paradigm === Paradigm.REACTIVE
// result.component is the transformed component
// result.metadata contains source and timestamp
static fromAny(input: any, sourceParadigm: Paradigm): DOPAdapter<S>

Creates an adapter from a component in any paradigm (reverse adaptation).

const functionalComponent = /* ... */;
const adapter = DOPAdapter.fromAny(functionalComponent, Paradigm.FUNCTIONAL);

const oopClass = /* ... */;
const adapter = DOPAdapter.fromAny(oopClass, Paradigm.OOP);

This enables paradigm detection and conversion for existing components.

ReactiveWrapper<S>

Direct reactive wrapper implementation (usually created via toReactive()).

import { ReactiveWrapper } from "@obinexusltd/obix-adapter";

const wrapper = new ReactiveWrapper(logic);

Methods

  • subscribe(callback): unsubscribe - Register state change listener
  • dispatch(actionName, ...args) - Execute action and notify subscribers
  • notify() - Manually trigger notifications
  • render() - Get rendered output for current state

Type Definitions

ComponentLogic<S>

The canonical data-oriented component representation:

interface ComponentLogic<S> {
  name: string;                              // Component name
  state: S;                                  // Initial state
  actions: Record<string, Action<S>>;        // Action map
  render: (context: ActionContext<S>) => any; // Render function
  metadata?: {                               // Optional metadata
    version?: string;
    description?: string;
    tags?: string[];
    [key: string]: any;
  };
}

ActionContext<S>

Context passed to action functions:

interface ActionContext<S> {
  state: S;           // Current state (mutable)
  [key: string]: any; // Other actions and utilities
}

Paradigm Enum

enum Paradigm {
  DATA_ORIENTED = "DATA_ORIENTED",
  FUNCTIONAL = "FUNCTIONAL",
  OOP = "OOP",
  REACTIVE = "REACTIVE",
}

Advanced Usage

Round-Trip Transformations

Convert between paradigms and back:

const adapter = new DOPAdapter(counterLogic);

// data → functional → data
const functional = adapter.toFunctional();
const reverseAdapter = DOPAdapter.fromAny(functional, Paradigm.FUNCTIONAL);
const logic = reverseAdapter.toDataOriented();

// data → OOP → reactive → data
const oopClass = adapter.toOOP();
const reverseAdapter = DOPAdapter.fromAny(oopClass, Paradigm.OOP);
const reactive = reverseAdapter.toReactive();
const finalAdapter = DOPAdapter.fromAny(reactive, Paradigm.REACTIVE);

Chaining Transformations

const adapter = new DOPAdapter(logic);
const OOPClass = adapter.toOOP();
const reverseAdapter = DOPAdapter.fromAny(OOPClass, Paradigm.OOP);
const functionalComponent = reverseAdapter.toFunctional();

Complex State Structures

The adapter works with any state type:

interface AppState {
  user: {
    name: string;
    age: number;
  };
  todos: Array<{ id: string; text: string; done: boolean }>;
}

const appLogic: ComponentLogic<AppState> = {
  name: "App",
  state: {
    user: { name: "Alice", age: 30 },
    todos: [],
  },
  actions: {
    updateUserName: ({ state }, name: string) => {
      state.user.name = name;
    },
    addTodo: ({ state }, text: string) => {
      state.todos.push({
        id: Math.random().toString(),
        text,
        done: false,
      });
    },
  },
  render: ({ state }) => ({
    greeting: `Hello, ${state.user.name}!`,
    todoCount: state.todos.length,
  }),
};

Error Handling

const adapter = new DOPAdapter(logic);
const reactive = adapter.toReactive();

try {
  reactive.dispatch("nonExistentAction");
} catch (error) {
  console.error(error.message); // "Action "nonExistentAction" not found"
}

Performance Considerations

  1. State Cloning: Each paradigm maintains its own isolated state copy for immutability
  2. Reactive Subscriptions: Multiple subscribers are O(n) per dispatch
  3. Functional Closures: Each function call has minimal overhead
  4. OOP Instances: Class instantiation is lightweight

Testing

The package includes comprehensive test coverage:

# Run tests once
npm test

# Watch mode
npm test:watch

Tests cover:

  • All paradigm transformations
  • State management and mutations
  • Action execution
  • Reactive subscriptions
  • Round-trip conversions
  • Error cases
  • Complex nested state

Architecture

Data-Oriented Foundation

The ComponentLogic is the canonical representation. All paradigms are derived transformations:

    ComponentLogic (DATA_ORIENTED)
         |
    _____|_____
   |     |     |
   v     v     v
  FP    OOP   RX

Reverse adapters allow:
  FP → DO, OOP → DO, RX → DO

State Management Strategy

Each paradigm implements state independently:

  • Functional: Closure-scoped, re-initialized per call
  • OOP: Instance property, mutable, persistent
  • Reactive: Proxy-wrapped for change detection, notifies subscribers

Action Execution

All actions receive an ActionContext containing:

  • Current mutable state
  • All other available actions
  • Any additional utilities

Actions mutate state directly; no explicit return needed.

Integration with OBIX

This adapter is the foundational pattern for OBIX components, enabling:

  1. Interoperability: Use any component with any framework/pattern
  2. Migration: Convert existing components between paradigms
  3. Composition: Mix paradigms in the same application
  4. Testing: Test components in any paradigm independently

License

MIT

Author

OBINexus [email protected]