npm package: @interopio/ng
Description: IO Connect library for Angular - Browser and Desktop
Author: Interop.IO
Latest version: 6.2.0

# @interopio/ng

## Overview

The [`@interopio/ng`](https://www.npmjs.com/package/@interopio/ng) library is a lightweight wrapper for the io.Connect JavaScript libraries - [`@interopio/desktop`](https://www.npmjs.com/package/@interopio/desktop) for **io.Connect Desktop** projects, and [`@interopio/browser`](https://www.npmjs.com/package/@interopio/browser) and [`@interopio/browser-platform`](https://www.npmjs.com/package/@interopio/browser-platform) for **io.Connect Browser** projects. It provides custom functions, modules, and services that can be used to initialize the io.Connect libraries and access the io.Connect APIs in your Angular apps.

## Installation

To install the library, execute the following command:

```cmd
npm install @interopio/ng
```

## Usage

The following examples demonstrate basic initialization of the `@interopio/ng` library in **io.Connect Desktop** and **io.Connect Browser** Angular apps that use standalone components.

> ℹ️ *For more details on using the `@interopio/ng` library and the io.Connect APIs in **io.Connect Desktop** projects, see the **io.Connect Desktop** [official documentation](https://docs.interop.io/desktop/getting-started/how-to/interop-enable-your-apps/angular/index.html).*

> ℹ️ *For more details on using the `@interopio/ng` library and the io.Connect APIs in **io.Connect Browser** projects, see the **io.Connect Browser** [official documentation](https://docs.interop.io/browser/developers/browser-client/angular/index.html).*

### io.Connect Desktop

In `app.config.ts` of the app:

```typescript
import { ApplicationConfig } from "@angular/core";
import { provideIoConnect } from "@interopio/ng";
import IODesktop, { IOConnectDesktop } from "@interopio/desktop";

const config: IOConnectDesktop.Config = {
    // Optional Browser Client configuration.
};

export const appConfig: ApplicationConfig = {
    providers: [
        provideIoConnect({
            desktop: {
                factory: IODesktop,
                config
            }
        })
    ]
};
```

In `main.ts` of the app:

```javascript
import { bootstrapApplication } from "@angular/platform-browser";
import { appConfig } from "./app/app.config";
import { App } from "./app/app";

bootstrapApplication(App, appConfig);
```

### io.Connect Browser

#### Main App

In `app.config.ts` of the Main app:

```javascript
import { ApplicationConfig } from "@angular/core";
import { provideIoConnect } from "@interopio/ng";
import IOBrowserPlatform, { IOConnectBrowserPlatform } from "@interopio/browser-platform";

// Main app configuration.
const config: IOConnectBrowserPlatform.Config = {
    licenseKey: "my-license-key"
};

export const appConfig: ApplicationConfig = {
    providers: [
        provideIoConnect({
            browserPlatform: {
                factory: IOBrowserPlatform,
                config
            }
        })
    ]
};
```

In `main.ts` of the Main app:

```javascript
import { bootstrapApplication } from "@angular/platform-browser";
import { appConfig } from "./app/app.config";
import { App } from "./app/app";

bootstrapApplication(App, appConfig);
```

#### Browser Client

In `app.config.ts` of the Browser Client:

```typescript
import { ApplicationConfig } from "@angular/core";
import { provideIoConnect } from "@interopio/ng";
import IOBrowser, { IOConnectBrowser } from "@interopio/browser";

const config: IOConnectBrowser.Config = {
    // Optional Browser Client configuration.
};

export const appConfig: ApplicationConfig = {
    providers: [
        provideIoConnect({
            browser: {
                factory: IOBrowser,
                config
            }
        })
    ]
};
```

In `main.ts` of the Browser Client:

```javascript
import { bootstrapApplication } from "@angular/platform-browser";
import { appConfig } from "./app/app.config";
import { App } from "./app/app";

bootstrapApplication(App, appConfig);
```

## Testing

The package includes **unit** and **integration** tests.

#### Test Scripts

- **`npm test`** - Runs all tests (unit + integration)
- **`npm run test:unit`** - Runs only unit tests
- **`npm run test:integration`** - Runs only integration tests

#### Test Structure

```
test/
├── globals.d.ts              # Global type declarations for Chai/Sinon
├── helpers/
│   └── utils.ts              # All test utilities (factories, mocks, window, async)
└── integration/              # Integration tests
    └── initialization.spec.ts
├── unit/                     # Unit tests
│   ├── glue-config.service.spec.ts
│   ├── glue-initializer.service.spec.ts
│   ├── glue-store.service.spec.ts
│   ├── ng.module.spec.ts
│   └── provide-io-connect.spec.ts
```

#### Test Coverage

The tests use **Mocha**, **Chai**, and **Sinon**, and run in a headless Chrome browser via **Karma**. Global type declarations allow using `expect` and `sinon` without imports in test files.

**Unit Tests:**
- **IOConnectConfigService** - Configuration service that handles factory and config resolution, environment detection (desktop vs browser), settings merging, and config validation
- **IOConnectInitializer** - Initialization service that manages the io.Connect factory invocation, error handling, timeout behavior, and `holdInit` functionality
- **IOConnectStore** - State management service that provides reactive access to the io.Connect instance and initialization status via observables
- **IOConnectNg Module** - Module configuration and dependency injection setup using `forRoot()`
- **provideIoConnect()** - Standalone API for Angular 15+ that provides io.Connect services without modules

**Integration Tests:**
- **Initialization flow** - Full integration tests covering both module-based (`forRoot()`) and standalone (`provideIoConnect()`) initialization flows across all three internally used libraries: `@interopio/browser-platform`, `@interopio/browser`, and `@interopio/desktop`.
- **Successful initialization** - Verifies factory invocation, instance availability, and ready state emission
- **Error handling** - Tests factory rejection, missing factory scenarios, and error propagation
- **Config flow** - Validates config passing, window global fallbacks, and factory prioritization
- **holdInit behavior** - Tests blocking vs non-blocking initialization modes
- **API equivalence** - Ensures `forRoot()` and `provideIoConnect()` produce identical results