JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2
  • Score
    100M100P100Q51112F
  • License MIT

Jigx Mobile Development Kit - SDK for building Jigx applications

Package Exports

  • @jigx/mdk
  • @jigx/mdk/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@jigx/mdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Release Code Quality

Jigx MDK TypeScript Implementation

A comprehensive TypeScript MDK (Mobile Development Kit) for building mobile-first applications with the Jigx platform. This SDK provides a fluent API for creating offline-capable, data-driven mobile applications using Jigx's unique document-based architecture. The style of the MDK follows that of a CDK, i.e., a declarative SDK. It compiles to Jigx's YAML configuration format.

Guide

Overview

Jigx is a mobile-first application platform that enables developers to build offline-capable, enterprise-grade mobile applications. This SDK provides a TypeScript-based fluent API that compiles to Jigx's YAML configuration format.

Key Concepts

  • Mobile-First Architecture: All UI patterns optimized for mobile devices with bottom-action buttons and touch-friendly interfaces
  • Document-Based Storage: SQLite + JSON architecture for flexible, offline-capable data management
  • Expression System: Powerful JSONata-based expressions for dynamic data binding and transformations
  • Builder Pattern API: Intuitive fluent API with full TypeScript type safety and IntelliSense support

Features

Application Building

  • ApplicationBuilder: Main entry point for creating Jigx applications
  • Screen Types: List, Default, Calendar, Table, Grid, and Tab screens
  • Component Library: 50+ mobile-optimized UI components
  • Action System: Navigation, data operations, and user interactions
  • Data Management: Datasources, entities, and functions for data operations

Core SDK Modules

  • Screen SDK: All screen types with mobile-first layouts
  • Component SDK: UI components (forms, lists, charts, media, etc.)
  • Action SDK: User interactions, navigation, and data operations
  • Datasource SDK: Data providers (dynamic, local, REST, SQL)
  • Function SDK: Business logic (REST API, SQL queries, SOAP)
  • Widget SDK: Home screen widgets for quick access
  • Database SDK: Database connection configurations

Development Experience

  • Type Safety: Full TypeScript support with comprehensive type definitions
  • Fluent API: Intuitive method chaining for rapid development
  • IntelliSense: Rich IDE support with documentation and examples
  • Expression Helpers: CTX utilities for accessing runtime data
  • Validation: Built-in schema validation and error reporting

Installation

# Using npm
npm install @jigx/mdk

# Using yarn
yarn add @jigx/mdk

# Using bun
bun add @jigx/mdk

Quick Start

import { application } from '@jigx/mdk'

const app = application('my-app', 'My Mobile App')

// Create a customer list screen
const listScreen = app.addScreen.list('customer-list', 'Customers')
  .data('=@ctx.datasources.customers')

// Add list items
listScreen.addControl.listItem('customer-item')
  .title('=@ctx.current.item.name')
  .subtitle('=@ctx.current.item.email')
  .onPress.goto('customer-detail')
    .parameter('customerId', '=@ctx.current.item.id')

// Add bottom action button (mobile-first pattern)
listScreen.bottomPanel.buttons(1)
  .add.goto('Add Customer', 'customer-form')
  .style({ isPrimary: true })

// Build the application
const application = app.build()

Core Concepts

1. Mobile-First Design

All UI patterns are optimized for mobile devices:

  • Action buttons ALWAYS at screen bottom (max 3 visible)
  • Touch-optimized controls and layouts
  • Offline-first data synchronization

2. Document-Based Data Model

// All data stored as JSON documents
const datasource = app.addDatasource.sqlite('customers', 'dynamic')
  .entity('default/customers')
  .query(`
    SELECT 
      id,
      json_extract(data, '$.name') as name,
      json_extract(data, '$.email') as email
    FROM [default/customers]
    WHERE json_extract(data, '$.active') = true
  `)

3. Expression System

// Dynamic values with JSONata expressions
import { CTX } from '@jigx/mdk'

// Access datasources
CTX.datasources.expr('users')  // '=@ctx.datasources.users'

// Access component state  
CTX.components.expr('email', 'value')  // '=@ctx.components.email.state.value'

// Access navigation parameters
CTX.screen.inputs.expr('customerId')  // '=@ctx.jig.inputs.customerId'

Screen Types

List Screen

const listScreen = app.addScreen.list('products', 'Product Catalog')
  .data('=@ctx.datasources.products')
  .onRefresh.syncEntities()
    .entity('products')

Default Screen (Forms & Content)

const formScreen = app.addScreen.default('user-form', 'User Registration')

// Add form fields
formScreen.addControl.textField('name')
  .label('Full Name')
  .required(true)

formScreen.addControl.emailField('email')
  .label('Email Address')
  .required(true)

// Bottom action buttons
const buttons = formScreen.bottomPanel.buttons(2)
buttons.add.goto('Cancel', 'home')
buttons.add.executeEntity('Save')
  .style({ isPrimary: true })
  .dynamicData('users', 'create')
  .data({
    name: '=@ctx.components.name.state.value',
    email: '=@ctx.components.email.state.value'
  })

Calendar Screen

const calendarScreen = app.addScreen.calendar('events', 'Event Calendar')
  .data('=@ctx.datasources.events')
  .dateField('=@ctx.current.item.date')
  .titleField('=@ctx.current.item.title')

Table Screen

const tableScreen = app.addScreen.table('inventory', 'Inventory')
  .data('=@ctx.datasources.inventory')

tableScreen.addColumn('product', 'Product').width(200)
tableScreen.addColumn('quantity', 'Qty').width(80)
tableScreen.addColumn('price', 'Price').format('currency')

Data Providers

Dynamic Provider (Cloud-Synced)

app.addDatasource.sqlite('shared-data', 'dynamic')
  .entity('default/customers')
  .query(`SELECT id, data FROM [default/customers]`)

Local Provider (Device-Only)

app.addDatasource.sqlite('preferences', 'local')
  .entity('user-preferences')
  .query(`SELECT id, data FROM [user-preferences]`)

REST Function

const apiFunction = app.addFunction.rest('get-users', 'GET', 'https://api.example.com/users')
apiFunction.params.header('Authorization', 'Bearer =@ctx.solution.state.token')

SQL Function

const sqlFunction = app.addFunction.sql('get-customer', 'customer-db')
  .sql('SELECT * FROM customers WHERE id = @customerId')
sqlFunction.params.input('customerId', 'string')

Critical Jigx Patterns

❌ NEVER Do This

// WRONG - No inline buttons!
screen.addControl.button('save')

// WRONG - Direct column access
.query('SELECT name FROM users')

// WRONG - Too many visible buttons
screen.bottomPanel.buttons(4)

✅ ALWAYS Do This

// CORRECT - Buttons at screen bottom
screen.bottomPanel.buttons(2)
  .add.executeEntity('Save')

// CORRECT - Use json_extract
.query(`SELECT json_extract(data, '$.name') as name FROM users`)

// CORRECT - Max 3 visible buttons
screen.bottomPanel.buttons(3)

Component Examples

Form Components

// Text input
screen.addControl.textField('name')
  .label('Name')
  .placeholder('Enter your name')
  .required(true)

// Dropdown
screen.addControl.dropdown('category')
  .label('Category')
  .datasource('=@ctx.datasources.categories')
  .title('=@ctx.current.item.name')
  .value('=@ctx.current.item.id')

// Date picker
screen.addControl.datePicker('startDate')
  .label('Start Date')
  .minimumDate('=@now()')

List Components

// List item with swipe actions
const listItem = screen.addControl.listItem('product-item')
  .title('=@ctx.current.item.name')
  .subtitle('=$currency(@ctx.current.item.price)')
  .image('=@ctx.current.item.imageUrl')

// Swipe actions
listItem.swipeable.leftActions
  .addAction.goto('Edit', 'edit-product')
    .parameter('productId', '=@ctx.current.item.id')

listItem.swipeable.rightActions
  .addAction.executeEntity('Delete')
    .dynamicData('products', 'delete')
    .data({ id: '=@ctx.current.item.id' })

Chart Components

// Line chart
screen.addControl.lineChart('sales-chart')
  .data('=@ctx.datasources.sales')
  .xAxis('date')
  .yAxis('revenue')
  .height(300)

// Pie chart
screen.addControl.pieChart('category-distribution')
  .data('=@ctx.datasources.categories')
  .labelField('name')
  .valueField('count')

State Management

Application State (Global)

// Set state
action.setState('currentUser')
  .value({ id: '123', name: 'John' })

// Access state
CTX.application.state.expr('currentUser.name')

Screen State (Local)

// Set screen state
action.setScreenState('selectedTab')
  .value('products')

// Access screen state
'=@ctx.jig.state.selectedTab'

Component State

// Access component value
'=@ctx.components.email.state.value'

// Check if valid
'=@ctx.components.email.state.isValid'

Advanced Patterns

Master-Detail Navigation

// Master list
const list = app.addScreen.list('orders', 'Orders')
  .data('=@ctx.datasources.orders')

list.addControl.listItem('order-item')
  .title('=@ctx.current.item.orderNumber')
  .subtitle('=$currency(@ctx.current.item.total)')
  .onPress.goto('order-detail')
    .parameter('orderId', '=@ctx.current.item.id')
    .parameter('returnScreen', 'orders')

// Detail screen
const detail = app.addScreen.default('order-detail', 'Order Details')

// Add datasource for single order
detail.addDatasource.sqlite('order', 'dynamic')
  .entity('default/orders')
  .query(`
    SELECT id, data FROM [default/orders] 
    WHERE id = @orderId
  `)
  .parameter('orderId', '=@ctx.jig.inputs.orderId')

// Back navigation
detail.bottomPanel.buttons(1)
  .add.goto('Back', '=@ctx.jig.inputs.returnScreen')

Data Synchronization

// Initial sync on app load
app.onLoad.actionList('sequential')
  .actions.syncEntities()
    .dynamic()
    .entity('users')
    .entity('products')
    .entity('orders')

// Pull-to-refresh on screen
screen.onRefresh.syncEntities()
  .dynamic()
  .entity('orders')
  .onSuccess.notification('Success', 'Orders refreshed')
  .onError.notification('Error', 'Sync failed')

Complex Forms with Validation

const form = app.addScreen.default('product-form', 'New Product')

// Form fields with validation
form.addControl.textField('name')
  .label('Product Name')
  .required(true)
  .minLength(3)
  .maxLength(50)

form.addControl.numberField('price')
  .label('Price')
  .required(true)
  .minimum(0)
  .format('currency')

form.addControl.dropdown('category')
  .label('Category')
  .required(true)
  .datasource('=@ctx.datasources.categories')
  .title('=@ctx.current.item.name')
  .value('=@ctx.current.item.id')

// Conditional visibility
form.addControl.textField('discount')
  .label('Discount Code')
  .isVisible('=@ctx.components.price.state.value > 100')

// Form submission with validation
const buttons = form.bottomPanel.buttons(2)
buttons.add.goto('Cancel', 'products')
buttons.add.actionList('Save', 'sequential')
  .style({ isPrimary: true })
  .actions.executeEntity()
    .dynamicData('products', 'create')
    .data({
      name: '=@ctx.components.name.state.value',
      price: '=@ctx.components.price.state.value',
      category: '=@ctx.components.category.state.selected.value',
      discount: '=@ctx.components.discount.state.value'
    })
  .actions.syncEntities()
    .entity('products')
  .actions.goto('products')

Architecture

The SDK is organized into modular components:

  • Application SDK: Main application builder and configuration
  • Screen SDK: All screen types and layouts
  • Component SDK: UI components and controls
  • Action SDK: User interactions and navigation
  • Datasource SDK: Data management and queries
  • Function SDK: Business logic and integrations
  • Database SDK: Database connection configurations
  • Widget SDK: Home screen widgets

Documentation

Contributing

Contributions are welcome! Please read our Contributing Guide for details on our code of conduct and the process for submitting pull requests.

License

This project is licensed under the MIT License - see the LICENSE file for details.