npm package: @obinexusltd/obix-binding-java-kotlin
Description: OBIX Java/Kotlin Binding - Android native, enterprise backend
Author: OBINexus
Latest version: 0.1.1

# @obinexusltd/obix-binding-java-kotlin

OBIX Java/Kotlin binding — Android native, enterprise backend.

Connects the [libpolycall](https://github.com/obinexusltd) FFI/polyglot bridge to a Kotlin/Native compiled shared library via [`ffi-napi`](https://github.com/node-ffi-napi/node-ffi-napi).

## Package info

| Field | Value |
|---|---|
| **Name** | `@obinexusltd/obix-binding-java-kotlin` |
| **Version** | `0.1.0` |
| **License** | MIT |
| **Author** | OBINexus \<okpalan@protonmail.com\> |
| **Module type** | ESM (`"type": "module"`) |
| **Entry point** | `dist/index.js` |
| **Types** | `dist/index.d.ts` |
| **Published files** | `dist/` |
| **Publish access** | public |

## Scripts

| Script | Command | Description |
|---|---|---|
| `build` | `tsc` | Compile TypeScript sources to `dist/` |
| `test` | `vitest run` | Run smoke tests once (no watch) |

## Exports

The package exposes a single export:

```js
import { createJavaKotlinBinding } from '@obinexusltd/obix-binding-java-kotlin';
```

The main entry resolves via the `exports` map:

```json
{
  ".": {
    "import": "./dist/index.js",
    "types": "./dist/index.d.ts"
  }
}
```

## Optional dependencies

`ffi-napi` and `ref-napi` are listed as `optionalDependencies`. They are **not required** to import or use the package in stub/test mode — the binding gracefully falls back to no-op behaviour when they are absent.

Install them only when you intend to load a real Kotlin/Native shared library:

```sh
npm install ffi-napi ref-napi
```

| Package | Version | Purpose |
|---|---|---|
| `ffi-napi` | `^4.0.3` | Load and call symbols from a native `.so`/`.dll`/`.dylib` |
| `ref-napi` | `^3.0.3` | C type marshalling required by `ffi-napi` |

## Usage

### Stub mode (no native library)

Works out of the box with no extra installs. `invoke()` returns `MISSING_SYMBOL` until you supply your own `globalThis.__obixAbiInvoker`.

```ts
import { createJavaKotlinBinding } from '@obinexusltd/obix-binding-java-kotlin';

const binding = createJavaKotlinBinding({
  ffiPath: '/path/to/libpolycall.so',
  schemaMode: 'hybrid',
  memoryModel: 'gc',
});

await binding.initialize();
console.log(binding.isInitialized()); // true
await binding.destroy();
```

### Native mode (Kotlin/Native shared library)

Requires `ffi-napi` and `ref-napi` installed, and a compiled Kotlin/Native library that exports the [C ABI contract](#c-abi-contract).

```ts
import { createJavaKotlinBinding } from '@obinexusltd/obix-binding-java-kotlin';

const binding = createJavaKotlinBinding({
  ffiPath: '/path/to/libpolycall.so',
  schemaMode: 'polyglot',
  memoryModel: 'gc',
  jniEnabled: true,
  jniLibPath: './libobix-jk.so', // path to your compiled Kotlin/Native lib
});

await binding.initialize(); // loads the shared lib and wires __obixAbiInvoker
const result = await binding.invoke('com.example.MyClass#myMethod', [arg1, arg2]);
await binding.destroy();
```

## C ABI contract

The native library must export these symbols (use `@CName` in Kotlin/Native):

| Symbol | C signature | Description |
|---|---|---|
| `obix_jk_invoke` | `char* (const char*)` | Takes JSON envelope string, returns JSON result string |
| `obix_jk_memory_usage` | `char* ()` | Returns JSON `{heapUsedBytes, heapMaxBytes, nonHeapBytes, objectCount}` |
| `obix_jk_gc` | `void ()` | Triggers garbage collection |
| `obix_jk_load_class` | `char* (const char*)` | Returns JSON proxy descriptor for a class name |
| `obix_jk_create_thread_pool` | `char* (int)` | Returns a pool-id string |
| `obix_jk_free` | `void (char*)` | Frees any `char*` returned by the above |

Minimal Kotlin/Native example:

```kotlin
import kotlinx.cinterop.*

@CName("obix_jk_invoke")
fun invoke(envelopeJson: CPointer<ByteVar>?): CPointer<ByteVar> {
    val input = envelopeJson?.toKString() ?: return "{}".encodeToByteArray().toCValues().ptr
    // process envelope JSON ...
    return result.encodeToByteArray().toCValues().ptr
}

@CName("obix_jk_free")
fun free(ptr: CPointer<ByteVar>?) {
    ptr?.let { nativeHeap.free(it) }
}
```