A backend service that safely validates, stores, and executes user-submitted TypeScript code using the BubbleFlow framework.
This service allows users to:
- Write TypeScript code that extends
BubbleFlow - Submit it for validation and storage
- Execute stored flows on-demand with custom payloads
- TypeScript Validation - Uses the TypeScript compiler API to validate code
- Code Processing - Transpiles TypeScript and transforms ES modules for execution
- Sandboxed Execution - Runs user code in an isolated environment
- Database Storage - Stores processed code ready for fast execution
User Code (TypeScript) → Validation → Processing → Storage → Execution
- User submits TypeScript code with ES module imports
- Validation ensures the code is valid TypeScript and extends BubbleFlow
- Processing transpiles to JavaScript and transforms imports to work without a module system
- Storage saves the processed code to database (SQLite)
- Execution runs the code in a sandboxed environment with controlled dependencies
Create and store a new BubbleFlow.
Request:
{
"name": "My Flow",
"description": "A flow that processes webhooks",
"code": "import { BubbleFlow } from '@bubblelab/bubble-core';\n\nexport class MyFlow extends BubbleFlow<'webhook/http'> {...}",
"eventType": "webhook/http"
}Response:
{
"id": 1,
"message": "BubbleFlow created successfully"
}Execute a stored BubbleFlow with a payload.
Request:
{
"payload": {
"name": "John",
"email": "john@example.com"
}
}Response:
{
"executionId": 1,
"success": true,
"data": {
"message": "Hello, John!"
}
}import { BubbleFlow, AIAgentBubble } from '@bubblelab/bubble-core';
import type { BubbleTriggerEventRegistry } from '@bubblelab/bubble-core';
export class GreetingFlow extends BubbleFlow<'webhook/http'> {
async handle(payload: BubbleTriggerEventRegistry['webhook/http']) {
const ai = new AIAgentBubble({ message: 'Hello!' });
return { greeting: await ai.action() };
}
}const { BubbleFlow, AIAgentBubble } = __bubbleCore;
class GreetingFlow extends BubbleFlow {
async handle(payload) {
const ai = new AIAgentBubble({ message: 'Hello!' });
return { greeting: await ai.action() };
}
}User code runs in a sandboxed environment with:
- No filesystem access
- No network access (unless through provided bubbles)
- No require/import capabilities
- Only access to __bubbleCore and provided payload
- Prefixed console output for debugging
- Runtime: Bun
- Framework: Hono (lightweight Express alternative)
- Database: SQLite with Drizzle ORM
- Validation: TypeScript Compiler API
- Testing: Jest with supertest-like utilities
- Bun installed
- pnpm package manager
pnpm install# Start the server
bun run src/index.ts
# Run tests
pnpm test
# Run database migrations
bun run drizzle-kit push# Optional - defaults to file:./dev.db
DATABASE_URL=file:./dev.db
# For AI bubbles (if using)
GOOGLE_API_KEY=your-key-here// 1. Create a flow
const response = await fetch('http://localhost:3001/bubble-flow', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'Email Processor',
code: `
import { BubbleFlow } from '@bubblelab/bubble-core';
export class EmailFlow extends BubbleFlow<'webhook/http'> {
async handle(payload) {
return {
processed: true,
email: payload.body.email
};
}
}
`,
eventType: 'webhook/http',
}),
});
const { id } = await response.json();
// 2. Execute the flow
const result = await fetch(`http://localhost:3001/execute-bubble-flow/${id}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
payload: { email: 'user@example.com' },
}),
});- Validation: ~50ms (one-time during creation)
- Execution: ~0.1ms (using pre-processed code)
- Storage: Processed code is stored, avoiding re-processing
# Build image
docker build -t bubblelab-api .
# Run container
docker-compose upThe project includes comprehensive Jest tests:
# Run all tests
pnpm test
# Run specific test file
pnpm test -- bubble-flow.test.ts
# Test manually
bun run test-bubble-flow.ts[Your License Here]