@qt-test/apex-runtime
v0.1.0
Published
Mini-app runtime framework for APEX platform
Maintainers
Readme
@interswitch/apex-runtime
Mini-app runtime framework for APEX platform
This package provides the core runtime framework for APEX mini-apps, including app lifecycle management, page routing, component system, and reactivity.
Installation
npm install @interswitch/apex-runtimeUsage
App Definition
// app.js
import { createApp } from '@interswitch/apex-runtime';
createApp({
onLaunch(options) {
console.log('App launched with:', options);
},
onShow() {
console.log('App shown');
},
onHide() {
console.log('App hidden');
},
globalData: {
userInfo: null
}
});Page Definition
// pages/index/index.js
import { createPage } from '@interswitch/apex-runtime';
createPage({
data: {
message: 'Hello APEX!',
count: 0
},
onLoad(query) {
console.log('Page loaded with query:', query);
},
onShow() {
console.log('Page shown');
},
onReady() {
console.log('Page ready');
},
onHide() {
console.log('Page hidden');
},
onUnload() {
console.log('Page unloaded');
},
// Event handlers
handleTap() {
this.setData({
count: this.data.count + 1
});
},
// Async data update
async fetchData() {
const result = await apex.request({ url: '/api/data' });
this.setData({ items: result.data });
}
});Component Definition
// components/button/button.js
import { createComponent } from '@interswitch/apex-runtime';
createComponent({
properties: {
text: {
type: String,
value: 'Button'
},
type: {
type: String,
value: 'default' // 'default' | 'primary' | 'danger'
},
disabled: {
type: Boolean,
value: false
}
},
data: {
pressed: false
},
lifetimes: {
created() {
console.log('Component created');
},
attached() {
console.log('Component attached to page');
},
detached() {
console.log('Component detached');
}
},
methods: {
handleTap() {
if (!this.properties.disabled) {
this.triggerEvent('tap', { timestamp: Date.now() });
}
}
}
});Architecture
Dual-Thread Model
APEX uses a dual-thread architecture to ensure 60fps UI performance:
┌─────────────────────────────┐ ┌─────────────────────────────┐
│ LOGIC THREAD │ │ VIEW THREAD │
│ │ │ │
│ ┌───────────────────────┐ │ │ ┌───────────────────────┐ │
│ │ JavaScriptCore / V8 │ │ JSON │ │ WebView Renderer │ │
│ │ │ │ Patch │ │ │ │
│ │ • app.js execution │──┼──────────┼─▶│ • AXML rendering │ │
│ │ • State management │ │ │ │ • DOM manipulation │ │
│ │ • API calls │ │ │ │ • 60fps animations │ │
│ │ • Business logic │◀─┼──────────┼──│ • User interactions │ │
│ │ │ │ Events │ │ │ │
│ │ NO DOM ACCESS │ │ │ │ NO BUSINESS LOGIC │ │
│ └───────────────────────┘ │ │ └───────────────────────┘ │
└─────────────────────────────┘ └─────────────────────────────┘Why Dual-Thread?
- Scrolling and animations stay at 60fps regardless of JS processing
- Heavy computations don't block UI
- Better security isolation
Runtime Components
┌─────────────────────────────────────────────────────────┐
│ Mini-App Code │
│ (app.js, pages/*.js, components/*.js) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ @interswitch/apex-runtime │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ LogicThread │ │ ViewThread │ │ Component │ │
│ │ │ │ │ │ System │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ JSON Patch │ │ Router │ │ Events │ │
│ │ (RFC 6902) │ │ │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Reactivity │ │ Scheduler │ │ Lifecycle │ │
│ │ System │ │ │ │ Hooks │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ @interswitch/apex-sdk │
│ (Bridge communication layer) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Native Host App │
└─────────────────────────────────────────────────────────┘Runtime Usage
import { createRuntime } from '@interswitch/apex-runtime';
const runtime = createRuntime({
mode: 'single-thread', // or 'dual-thread' for production
appConfig: {
appId: 'my-app',
version: '1.0.0',
pages: ['/pages/index/index'],
},
initialRoute: '/pages/index/index',
debug: true,
});
// Register pages
runtime.registerPage(
'/pages/index/index',
{
data: { count: 0 },
onLoad(query) {
console.log('Page loaded', query);
},
handleTap() {
this.setData({ count: this.data.count + 1 });
},
},
template
);
// Start the runtime
await runtime.start();API Reference
App Lifecycle
| Event | Description |
|-------|-------------|
| onLaunch | Triggered when app is launched (once) |
| onShow | Triggered when app comes to foreground |
| onHide | Triggered when app goes to background |
| onError | Triggered when script error occurs |
| onPageNotFound | Triggered when page not found |
Page Lifecycle
| Event | Description |
|-------|-------------|
| onLoad | Triggered when page is loaded |
| onShow | Triggered when page is shown |
| onReady | Triggered when page rendering is complete |
| onHide | Triggered when page is hidden |
| onUnload | Triggered when page is unloaded |
| onPullDownRefresh | Triggered on pull-down refresh |
| onReachBottom | Triggered when scrolled to bottom |
| onShareAppMessage | Triggered when user shares |
Component Lifecycle
| Event | Description |
|-------|-------------|
| created | Component instance created |
| attached | Component attached to page |
| ready | Component layout complete |
| moved | Component moved in tree |
| detached | Component detached from page |
License
MIT
