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

@ouidesigner/oui-ion

v4.0.5

Published

Angular/Ionic renderer for OuIB JSON pages.

Readme

oui-ion

oui-ion is an Angular/Ionic renderer for OuIB JSON pages.

It receives a UIPage, parses its uiData, finds a parser for each node's type, and dynamically creates Ionic/Angular components. A JSON page definition such as a Column with Text and OButton children becomes a real Angular/Ionic view at runtime.

Mental Model

The render flow is:

  1. The host app imports OUIIonModule.forChild(config) or registers provideOUIIon(config).
  2. OUIIon is created with app config, service bridges, and parser registrations.
  3. A page is selected through navigation, resolved by code, or passed to a modal.
  4. OUIDisplayComponent passes the page into OUIIonPageRender.
  5. OUIIonPageRender loads related service pages, parses page.uiData, creates UIPageState, and creates an OUIDefaultClickListener.
  6. The root node is rendered by <app-ion-oui>.
  7. IonOUI calls OUIIon.buildComponent(data).
  8. OUIIon finds the parser matching data.type.
  9. The parser dynamically creates the Angular component.
  10. Child components repeat the same process recursively.

Public API

The public surface is exported from src/public-api.ts.

Important exports:

  • OUIIonModule and provideOUIIon for Angular setup.
  • OUIIon as the main runtime/facade.
  • OUIIonService as the bridge to HTTP, navigation, alerts, loading, media, and platform services.
  • OUIIonPageRender for rendering a UIPage.
  • OUIDisplayComponent as the route/modal wrapper around the renderer.
  • OUIIonParser and OUIAbstractIonParser for custom parser implementations.
  • OUIDefaultClickListener and helper utilities for OuIB runtime behavior.
  • PinUtil / pin helpers from pin-utils.

Angular Setup

Use the module API in Angular module based apps:

import { OUIIonModule } from '@ouidesigner/oui-ion';

@NgModule({
  imports: [
    OUIIonModule.forChild({
      serverUrl: 'https://example.com',
      appId: 'app-id',
      appSecret: 'app-secret',
      appPackage: 'com.example.app',
      pinCrypto: {
        reference: environment.ouiPinCryptoReference,
        keySize: environment.ouiPinCryptoKeySize,
        specialsChars: environment.ouiPinCryptoSpecials,
      },
      userData: {
        id: 'user-id',
        name: 'User Name',
      },
      platform: 'md',
      pageViewRoute: '/mini-pages',
    }),
  ],
})
export class FeatureModule {}

Use the provider API in standalone apps:

import { provideOUIIon } from '@ouidesigner/oui-ion';

export const appConfig = {
  providers: [
    provideOUIIon({
      serverUrl: 'https://example.com',
      appId: 'app-id',
      appSecret: 'app-secret',
      appPackage: 'com.example.app',
      pinCrypto: {
        reference: environment.ouiPinCryptoReference,
        keySize: environment.ouiPinCryptoKeySize,
        specialsChars: environment.ouiPinCryptoSpecials,
      },
      userData: {
        id: 'user-id',
        name: 'User Name',
      },
      platform: 'ios',
    }),
  ],
};

OUIIonModule also registers a child route with path: ':page' and renders it through OUIDisplayComponent.

PIN Crypto Configuration

pinCrypto is required when mini-app scripts use __secure__(...) or when tightened auth encrypts API endpoint segments. Keep those values in the consuming host app configuration or environment files. Do not hardcode host PIN crypto material in @ouidesigner/oui-ion.

provideOUIIon({
  serverUrl: environment.ouibServerUrl,
  appId: environment.ouibAppId,
  appSecret: environment.ouibAppSecret,
  appPackage: environment.appPackage,
  pinCrypto: {
    reference: environment.ouiPinCryptoReference,
    keySize: environment.ouiPinCryptoKeySize,
    specialsChars: environment.ouiPinCryptoSpecials,
  },
});

Core Runtime

OUIIon in src/lib/o-ui.ts owns the runtime state:

  • parser registration and lookup
  • page and service page loading
  • page cache
  • app info and user config
  • MEvento global functions
  • navigation and modal bridge
  • API calls
  • asset URL resolution
  • theme variables
  • simulation flag

Rendering depends on data.type. If no parser is registered for a type, that node renders nothing.

Page Rendering

OUIDisplayComponent is a thin wrapper. For normal route navigation it reads the selected page and nav params from oui.exchange. For modal rendering, the page and params are passed directly through component inputs.

OUIIonPageRender does the actual page bootstrapping:

  • calls oui.loadService(page.code) so nested templates/fragments can resolve service pages
  • parses page.uiData
  • creates UIPageState, StateHolder, OGlobalFormState, and output state
  • creates the page click handler
  • runs __init__ when the JSON has the structured __view__ format
  • renders either uiData.__view__ or the whole parsed JSON tree

Structured pages look like this:

{
  __init__: 'SOME_MEVENTO_SETUP()',
  __view__: {
    type: 'Column',
    children: [],
  },
}

Plain pages can render the JSON root directly:

{
  type: 'Root',
  child: {
    type: 'Text',
    value: 'Hello',
  },
}

Parser System

Every renderable node is handled by an OUIIonParser.

export interface OUIIonParser {
  type: string;
  componentType: Type<OUIIonElement>;
  parse(
    data: { [k: string]: any },
    ouiHost: IonOUIDirective,
    clickHandler?: OUIDefaultClickListener,
    options?: any,
  ): OUIIonElement;
  export(element: OUIIonElement): { [k: string]: any };
}

Most parsers extend OUIAbstractIonParser, which:

  1. clears the host ViewContainerRef
  2. creates the parser's Angular component
  3. assigns data, clickHandler, mode, and layout constraint options

The built-in parser catalog lives in src/lib/parsers/default-parsers.ts.

Common parser families:

  • page shell and layout: Root, SingleChildScrollView, Container, Padding, SizedView, Stack, Positioned
  • text and media: Text, DynamicText, Image, Icon, QrCode
  • flex layout: Row, Column, Expanded, Flexible, WrapView
  • buttons: OButton, TextButton, ElevatedButton, OutlinedButton
  • forms: Form, TextField, DateTime, Switch, Slider, Checkbox, Dropdown, Selector, FilePicker
  • data and control views: FutureView, ListView, GridView, Stated, Controller, Interval, VisibilityControl, DelayedView
  • composition: Template

Dynamic Values

Helpers in src/lib/helpers.ts resolve dynamic string values used by many parsers:

  • normal strings are passed through translation
  • strings beginning with % are treated as translation keys
  • strings wrapped in ${...} are executed by the current MEvento VM

Example:

{
  type: 'Text',
  value: '${USER.name}',
}

MEvento Integration

OUIIon registers runtime functions into MEvento during initialization. These include storage helpers, logging, map/list helpers, encoding utilities, date/time helpers, math/string helpers, navigation, modal behavior, API execution, asset resolution, and secure PIN helpers.

OUIDefaultClickListener is the main bridge between page actions, MEvento execution, API calls, form state, navigation, and the current UIPageState.

Because OuIB page JSON can include MEvento expressions and scripts, page definitions are not only static UI data; they can also execute behavior.

Service Bridge

OUIIonService wraps platform and app services used by the runtime:

  • httpGet() and httpPost() with OuIB common headers
  • alerts, toasts, loading indicators, and confirmations
  • navigation and back behavior
  • modal dismissal
  • camera/image picking
  • barcode scanning
  • date formatting

Common request headers include SDK version, user id/name, app id/secret, app package, and language.

Page Loading

OUIIon loads pages through the consumer API:

  • app services list: GET /api/v1/c/apps/{appId}/services
  • single service/page by code: GET /api/v1/c/apps/{appId}/services/{code}
  • pages belonging to a service: GET /api/v1/c/apps/{appId}/{code}/pages

The runtime keeps a cached page list and per-service page caches. page(code) resolves from cache first and falls back to _loadPage(code).

Hosts can provide a custom UIPageResolver when page resolution needs to come from another source.

Preview And Simulation

simulation is a runtime flag used for mock/no-backend flows. It is not a preview/draft switch. When simulation is enabled, parts of the runtime skip real backend calls and some components use simulation data.

To preview unreleased pages, the host app and backend must expose draft or build selection through the consumer API contract, for example with a query/header such as preview=true or build=74. oui-ion can forward query params through OUIIonService.httpGet, but it does not call admin-only metadata endpoints by default.

Adding A Parser

To add a new node type:

  1. Create a standalone component implementing OUIIonElement.
  2. Create a parser implementing OUIIonParser or extending OUIAbstractIonParser.
  3. Set the parser type to the JSON node type.
  4. Add the parser to defaultParsers or pass it through OUIIonOptions.parsers.

Example:

export class MyWidgetParser extends OUIAbstractIonParser {
  type = 'MyWidget';
  componentType = MyWidgetComponent;
}

JSON:

{
  type: 'MyWidget',
  value: 'Hello',
}

Development

Run commands from the workspace root (D:\COMMON\ouib-angular-lab).

GitLab registry: publish and install guides live in the workspace docs/registry-setup.md and docs/consuming-packages.md.

Build once:

npx ng build oui-ion

Build on changes:

npx ng build oui-ion --watch

Run unit tests:

npx ng test oui-ion

Run the package scripts from the library folder if needed:

npm run build:lib
npm run build:dev
npm test

Notes And Risks

  • OUIConfig is static/global runtime state; avoid creating multiple conflicting runtime configs in the same app shell.
  • Parser lookup is string based. A typo in data.type silently produces no UI.
  • uiData can execute MEvento code. Treat loaded pages as trusted app content.
  • Several runtime paths currently log to the console unconditionally.
  • simulation should not be reused for previewing draft pages because it changes backend behavior.