UNPKG

@jigx/mdk

Version:

Jigx Mobile Development Kit - SDK for building Jigx applications

448 lines (358 loc) 12.9 kB
[![Release](https://github.com/jigx-com/jigx-mdk/actions/workflows/release.yml/badge.svg)](https://github.com/jigx-com/jigx-mdk/actions/workflows/release.yml) [![Code Quality](https://github.com/jigx-com/jigx-mdk/actions/workflows/code-quality.yml/badge.svg)](https://github.com/jigx-com/jigx-mdk/actions/workflows/code-quality.yml) # 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](./dist/docs/DOCS.md) ## 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 ```bash # Using npm npm install @jigx/mdk # Using yarn yarn add @jigx/mdk # Using bun bun add @jigx/mdk ``` ## Quick Start ```typescript 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 ```typescript // 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 ```typescript // 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 ```typescript const listScreen = app.addScreen.list('products', 'Product Catalog') .data('=@ctx.datasources.products') .onRefresh.syncEntities() .entity('products') ``` ### Default Screen (Forms & Content) ```typescript 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 ```typescript const calendarScreen = app.addScreen.calendar('events', 'Event Calendar') .data('=@ctx.datasources.events') .dateField('=@ctx.current.item.date') .titleField('=@ctx.current.item.title') ``` ### Table Screen ```typescript 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) ```typescript app.addDatasource.sqlite('shared-data', 'dynamic') .entity('default/customers') .query(`SELECT * FROM [default/customers]`) ``` ### Local Provider (Device-Only) ```typescript app.addDatasource.sqlite('preferences', 'local') .entity('user-preferences') .query(`SELECT * FROM [user-preferences]`) ``` ### REST Function ```typescript const apiFunction = app.addFunction.rest('get-users', 'GET', 'https://api.example.com/users') apiFunction.params.header('Authorization', 'Bearer =@ctx.solution.state.token') ``` ### SQL Function ```typescript 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 ```typescript // 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 ```typescript // 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 ```typescript // 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 ```typescript // 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 ```typescript // 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) ```typescript // Set state action.setState('currentUser') .value({ id: '123', name: 'John' }) // Access state CTX.application.state.expr('currentUser.name') ``` ### Screen State (Local) ```typescript // Set screen state action.setScreenState('selectedTab') .value('products') // Access screen state '=@ctx.jig.state.selectedTab' ``` ### Component State ```typescript // Access component value '=@ctx.components.email.state.value' // Check if valid '=@ctx.components.email.state.isValid' ``` ## Advanced Patterns ### Master-Detail Navigation ```typescript // 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 * 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 ```typescript // 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 ```typescript 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 - [Official Jigx Documentation](https://docs.jigx.com) - [Jigx SDK Guide](./dist/docs/DOCS.md) - Comprehensive guide with examples and patterns - [SDK API Reference](./docs/API.md) - [Migration Guide](./docs/MIGRATION.md) - [Best Practices](./docs/BEST_PRACTICES.md) ## Contributing Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) 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](LICENSE) file for details.