@klyntlabs/miniapp-sdk
v0.0.7
Published
Mini-App SDK for Klynt IDE - provides registration, messaging, state isolation, and lifecycle management for mini-apps
Downloads
394
Readme
@klynt/miniapp-sdk
Mini-App SDK for the Klynt IDE platform. Provides the foundation for building reactive, isolated mini-applications within the workspace environment.
Overview
The Mini-App SDK enables developers to create mini-apps that:
- Register with the workspace runtime via
defineMiniApp - Communicate through the
paneBusmessage bus - Maintain isolated state with
usePaneState - Handle lifecycle events and errors gracefully
Installation
pnpm add @klynt/miniapp-sdkQuick Start
import { useEffect } from 'react';
import {
defineMiniApp,
paneBus,
usePaneState,
MiniAppWrapper,
} from '@klynt/miniapp-sdk';
// Define your mini-app
const MyMiniApp = defineMiniApp({
id: 'my-miniapp',
name: 'My Mini App',
capabilities: ['editor:read', 'workspace:layout:read'],
component: MyComponent,
});
// Use state isolation
function MyComponent() {
const [state, setState] = usePaneState('my-state', { count: 0 });
// Subscribe to messages
useEffect(() => {
return paneBus.subscribe('editor.documentChanged', (msg) => {
// Handle message
});
}, []);
return <div>Count: {state.count}</div>;
}API Reference
defineMiniApp(config)
Registers a mini-app with the workspace runtime.
import { defineMiniApp } from '@klynt/miniapp-sdk';
const MyMiniApp = defineMiniApp({
// Required fields
id: 'my-editor-extension', // kebab-case, lowercase
name: 'My Editor Extension',
component: MyComponent,
// Optional fields
description: 'An editor extension for code analysis',
version: '1.0.0',
capabilities: ['editor:read', 'editor:onChange'],
optionalCapabilities: ['editor:write'],
category: 'editor',
allowMultiple: true,
autoRegister: false,
// Lifecycle hooks
hooks: {
onMount: (ctx) => {
// Called when mini-app mounts
// ctx: { paneId, capabilities, miniAppId, dimensions }
return () => {
// Optional cleanup function
};
},
onUnmount: (ctx) => {
// Called when mini-app unmounts
},
onFocus: (ctx) => {
// Called when pane gains focus
},
onBlur: (ctx) => {
// Called when pane loses focus
},
onMessage: (msg, ctx) => {
// Called when paneBus message is received
},
onLayoutChange: (dimensions, ctx) => {
// Called when pane is resized
},
},
});ID Validation Rules:
- Must start with a lowercase letter
- Can contain lowercase letters, numbers, and hyphens
- Must not end with a hyphen
- Examples:
my-editor,terminal,challenge-runner-v2
Throws:
MINIAPP.REGISTRATION.INVALID_ID- Invalid ID formatMINIAPP.REGISTRATION.INVALID_MANIFEST- Invalid config/capabilitiesMINIAPP.REGISTRATION.INVALID_HOOK- Non-function hookMINIAPP.REGISTRATION.MISSING_COMPONENT- Missing componentMINIAPP.REGISTRATION.DUPLICATE_ID- ID already registered (whenautoRegister: true)
miniAppRegistry
Global registry for managing registered mini-apps:
import { miniAppRegistry, defineMiniApp } from '@klynt/miniapp-sdk';
// Manual registration
const myApp = defineMiniApp({ id: 'my-app', name: 'My App', component: () => null });
miniAppRegistry.register(myApp);
// Or auto-register on creation
const autoApp = defineMiniApp({
id: 'auto-app',
name: 'Auto App',
component: () => null,
autoRegister: true,
});
// Query registry
miniAppRegistry.has('my-app'); // true
miniAppRegistry.get('my-app'); // MiniAppDefinition
miniAppRegistry.getAll(); // MiniAppDefinition[]
miniAppRegistry.size; // 2
// Unregister
miniAppRegistry.unregister('my-app'); // true
miniAppRegistry.clear(); // Clear all (useful for tests)paneBus
Message bus for cross-pane communication:
emit(topic, payload)- Send a messagesubscribe(topic, handler)- Listen for messagesrequest(topic, payload)- Request/response pattern
Accessing PaneBus
Recommended Patterns
Pattern 1: Import paneBus directly (simplest)
import { paneBus } from '@klynt/miniapp-sdk';
paneBus.emit('topic', payload);
paneBus.subscribe('topic', handler);Pattern 2: Use runtime hook (React components)
import { useRuntime } from '@klynt/miniapp-sdk';
function MyComponent() {
const { paneBus } = useRuntime();
useEffect(() => {
return paneBus.subscribe('topic', handler);
}, [paneBus]);
}Pattern 3: Get global runtime (non-React code)
import { getGlobalRuntime } from '@klynt/miniapp-sdk';
const { paneBus } = getGlobalRuntime();
paneBus.emit('topic', payload);Debugging
The current runtime instance is available at window.__KLYNT_PANEBUS_RUNTIME__ for debugging in browser DevTools:
// In browser console
window.__KLYNT_PANEBUS_RUNTIME__.paneBus
window.__KLYNT_PANEBUS_RUNTIME__.debug?.getMessageHistory()IMPORTANT: This is for debugging only. Application code should use the import patterns above.
usePaneState(key, initialState)
Hook for pane-scoped state isolation.
MiniAppWrapper
HOC providing error boundaries and lifecycle management.
Capabilities
Mini-apps declare required capabilities in their manifest:
const CAPABILITIES = {
editor: ['read', 'write', 'onChange', 'subscribe'],
terminal: ['read', 'execute', 'subscribe'],
runtime: ['execute', 'logs', 'subscribe'],
workspace: ['layout:read', 'layout:write'],
lesson: ['read', 'navigate'],
challenge: ['submit', 'validate'],
};Architecture
See the architecture documentation for details on:
- ADR-1: Mini-app registration model
- ADR-2: paneBus routing
- ADR-3: Capability enforcement
- ADR-4: State isolation
- ADR-5: Lifecycle hooks
- ADR-6: Error boundaries
