Skip to content

EventFlow Language Strategy & SaaS Architecture Proposal ​

One DSL. Any Language. Cloud-Powered.

Version: Draft 0.1 Date: December 2024


1. Executive Summary ​

EventFlow is a natural language DSL for executable state machines. The core question: Which programming language should EventFlow be implemented in?

This proposal argues for a language-agnostic architecture where:

  • The DSL and runtime are implemented in a primary language (PHP initially)
  • Bindings allow users to write implementations in their preferred language
  • A SaaS layer provides cloud-powered features for all users

Core Philosophy ​

Write flows once. Run anywhere.

Your bindings, your language.

Open source core. Cloud-powered extras.

Key Decisions ​

  1. PHP-first implementation - Fastest path to market for the primary author
  2. Multi-language bindings - PHP first, then TypeScript, Python, Go (based on demand)
  3. Freemium SaaS - Core open source, cloud features paid
  4. Rust migration path - Performance-critical components later (if needed)

2. Motivation & Problem Statement ​

2.1 The Language Dilemma ​

Every DSL faces a choice: which host language? Each has trade-offs:

LanguageProsCons
PHPLaravel ecosystem, author expertiseAsync limitations, perception
TypeScriptUniversal, great DXRuntime complexity
RustPerformance, WASMLearning curve, slower iteration
GoSimplicity, concurrencyLess expressive for DSLs

2.2 The Real Insight ​

The language of the core runtime matters less than the language of user bindings:

User writes .flow file → Describes WHAT happens
User writes bindings  → Implements HOW it happens (their language)

A Laravel developer wants PHP bindings. A Django developer wants Python. Neither cares what the parser is written in.

2.3 Goals ​

  1. Maximize author velocity - Ship fastest with known tools
  2. Maximize user adoption - Support popular languages
  3. Enable SaaS monetization - Cloud features justify paid tiers
  4. Preserve migration options - Don't paint into a corner

3. Language Strategy ​

3.1 Architecture Overview ​

┌─────────────────────────────────────────────────────────────────┐
│                     EventFlow DSL (.flow files)                  │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                     EventFlow Core (PHP)                         │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │
│  │   Parser    │ │   Runtime   │ │   Queue     │ │  Analytics │ │
│  │   (Pest)    │ │   Engine    │ │   System    │ │   Engine   │ │
│  └─────────────┘ └─────────────┘ └─────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────────────┘
                              │
           ┌──────────────────┼──────────────────┐
           │                  │                  │
           ▼                  ▼                  ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│  PHP Bindings   │ │   TS Bindings   │ │ Python Bindings │
│  (Laravel)      │ │   (Node/Deno)   │ │   (FastAPI)     │
└─────────────────┘ └─────────────────┘ └─────────────────┘

3.2 Core Components (PHP) ​

ComponentTechnologyRationale
ParserPest (PEG)Elegant, readable grammar
RuntimeLaravel coreQueue, cache, events built-in
CLISymfony ConsoleStandard, powerful
QueueLaravel HorizonEnterprise-grade, observable
StorageEvent sourcingSpatie package mature

3.3 Binding Interface ​

Each language binding implements a standard interface:

php
// PHP Binding Interface (reference implementation)
interface Guard {
    public function check(Context $context): bool;
}

interface Action {
    public function execute(Context $context): void;
}

interface Assertion {
    public function assert(Context $context): void;
}

The runtime calls bindings via:

  1. In-process (PHP bindings) - Direct method calls
  2. HTTP/gRPC (other languages) - Service mesh pattern
  3. stdio (CLI tools) - JSON protocol

4. PHP-First Implementation ​

4.1 Why PHP? ​

For THIS project, by THIS author:

FactorPHP Advantage
Author expertise10+ years Laravel experience
Time to market2-3x faster than learning new stack
EcosystemLaravel Horizon, Octane, Livewire ready
Proven at scaleLaravel Vapor, Forge handle millions

4.2 Addressing PHP Concerns ​

Concern: "PHP isn't async" Solution: Laravel Octane + Swoole provides true async

Concern: "PHP won't scale" Solution: Horizon handles 10k+ events/sec with proper infra

Concern: "PHP perception" Solution: SaaS users don't see implementation. Open source users choose bindings.

4.3 Tech Stack ​

Laravel 11 Application
├── Octane (Swoole)        # Async, long-running processes
├── Horizon                 # Queue management, monitoring
├── Inertia.js + Vue       # Full-stack SPA experience
├── Spatie Event Sourcing  # Event store
├── Pest PHP               # Testing
└── Livewire               # Real-time UI components

5. Multi-Language Bindings ​

5.1 Binding Discovery ​

Each language has its own pattern:

php
// PHP: Attributes
#[Guard('cart is not empty')]
class CartNotEmpty implements Guard { }

// TypeScript: Decorators
@guard('cart is not empty')
class CartNotEmpty implements Guard { }

// Python: Decorators
@guard('cart is not empty')
class CartNotEmpty(Guard): pass

5.2 Binding Communication ​

┌──────────────────┐     JSON/gRPC      ┌──────────────────┐
│  EventFlow Core  │◄──────────────────►│  Binding Service │
│  (PHP Runtime)   │                    │  (Any Language)  │
└──────────────────┘                    └──────────────────┘
        │
        │ Protocol:
        │ {
        │   "action": "check_guard",
        │   "pattern": "cart is not empty",
        │   "context": { "cart": [...] }
        │ }
        │
        ▼
        Response: { "result": true }

5.3 Language Priority ​

Phase 1 (Year 1): PHP Only

  • Focus on perfecting the PHP/Laravel integration
  • No distraction from multi-language complexity
  • Validate product-market fit first

Phase 2 (Year 2+, if demand exists):

  1. TypeScript - Largest community
  2. Python - AI/ML integration
  3. Go - High-performance microservices

Decision: Ship PHP bindings first. Other languages only after proven demand.


6. SaaS Business Model ​

6.1 Open Source vs Paid ​

FeatureOpen SourceSaaS
Parser & runtime✓✓
CLI tools✓✓
All bindings✓✓
Local testing✓✓
Cloud dashboard-✓
Team collaboration-✓
Managed queues-✓
Analytics & insights-✓
Enterprise support-✓

6.2 Pricing Tiers ​

Free (Community) ​

  • Full open source package
  • Self-hosted everything
  • Community support (GitHub Issues, Discord)
  • Target: Learners, hobbyists, evaluation

Pro ($29/month per developer) ​

  • Cloud diagram generation
  • Test runner as a service
  • Basic analytics dashboard
  • Email support
  • Target: Solo developers, freelancers

Team ($99/month for 5 developers) ​

  • Everything in Pro
  • Real-time collaboration
  • Version history
  • Team analytics
  • Slack integration
  • Target: Startups, small teams

Enterprise ($499/month base + per-seat) ​

  • Everything in Team
  • SSO/SAML
  • Managed event queue hosting
  • Custom integrations
  • SLA guarantee
  • Dedicated support
  • On-premise option
  • Target: Large companies, regulated industries

6.3 Monetization Opportunities (Detailed) ​

Tier 1: Low Effort / High Value ​

FeatureEffortValueNotes
Cloud DiagramsLowHighShareable links, PDF export, embed codes
Online EditorMediumHighMonaco-based, syntax highlighting, validation
Analytics DashboardMediumHighCloud-hosted metrics, no self-hosting needed
Educational ContentLowMediumVideo courses, workshops, certifications

Tier 2: Medium Effort / High Value ​

FeatureEffortValueNotes
Team CollaborationMediumHighReal-time editing, comments, review workflow
Version ControlMediumMediumGit-like history, branching, diffs
Test Runner ServiceMediumMediumCloud CI without setup
Flow MarketplaceMediumMediumCommunity templates, premium templates

Tier 3: High Effort / Variable Value ​

FeatureEffortValueNotes
Hosted RuntimeVery HighHighFull machine hosting - complex infra
Managed QueuesHighHighEnterprise reliability, SLA
Custom IntegrationsHighMediumConsulting-like, per-customer
On-Premise LicenseMediumHighEnterprise compliance requirement
                    HIGH VALUE
                        │
    ┌───────────────────┼───────────────────┐
    │                   │                   │
    │  Cloud Diagrams   │  Team Collab      │
    │  Online Editor    │  Hosted Runtime   │
    │  Analytics        │  Managed Queues   │
    │                   │                   │
LOW ├───────────────────┼───────────────────┤ HIGH
EFFORT                  │                   EFFORT
    │                   │                   │
    │  Edu Content      │  Custom Integ.    │
    │  Marketplace      │  On-Premise       │
    │                   │                   │
    └───────────────────┼───────────────────┘
                        │
                    LOW VALUE

Start with: Cloud Diagrams → Online Editor → Analytics (hosted) → Team Collaboration

Hosted Runtime Discussion ​

Hosting user's flow machines is high effort because:

  • Multi-tenant isolation complexity
  • Per-user scaling
  • Security (user code execution)
  • Database per tenant
  • Queue isolation
  • Compliance (data residency)

Alternative approach: Provide deployment templates for:

  • Laravel Vapor (AWS)
  • Laravel Forge (any VPS)
  • Docker + Kubernetes
  • Self-hosted guides

This way users deploy to their own infra, but we provide excellent tooling.

6.4 Value Justification ​

Why pay when core is free?

Pain PointFree SolutionPaid Solution
"I need diagrams for stakeholders"Manual MermaidOne-click cloud render, shareable link
"CI/CD is complex"Self-manage runnersCloud test runner, GitHub Action
"Team needs to collaborate"Git + merge conflictsReal-time editing, comments
"I need analytics"Build custom dashboardsPre-built funnels, insights
"We need support"Community/self-helpPriority response, SLA

7. Technical Architecture (SaaS) ​

7.1 Infrastructure ​

┌─────────────────────────────────────────────────────────────────┐
│                        CloudFlare                                │
│                    (CDN, DDoS protection)                        │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                     Laravel Vapor (AWS)                          │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐                │
│  │   Web App   │ │   API       │ │  Queue      │                │
│  │  (Inertia)  │ │  (Sanctum)  │ │  Workers    │                │
│  └─────────────┘ └─────────────┘ └─────────────┘                │
└─────────────────────────────────────────────────────────────────┘
         │                  │                  │
         ▼                  ▼                  ▼
┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│   Aurora    │    │    SQS      │    │  S3         │
│ (PostgreSQL)│    │  (Queues)   │    │ (Storage)   │
└─────────────┘    └─────────────┘    └─────────────┘

7.2 Multi-tenancy ​

php
// Tenant isolation via Laravel's native multi-tenancy
// Each customer gets isolated:
// - Database schema (shared DB, separate tables)
// - Queue prefix
// - Storage directory
// - Event bus namespace

7.3 Scaling Path ​

StageUsersInfrastructure
Launch0-100Single Vapor deployment
Growth100-1000Multi-region Vapor
Scale1000-10000Dedicated workers, read replicas
Enterprise10000+Kubernetes, dedicated clusters

8. Migration Path (PHP → Rust) ​

8.1 When to Consider Rust ​

Trigger points for Rust migration:

  1. Parser bottleneck: >1 second parse time for large files
  2. Event throughput: >50,000 events/second needed
  3. WASM requirement: Browser-native runtime requested
  4. Memory pressure: PHP memory limits hit in workers

8.2 Migration Strategy ​

Phase 1: PHP Only (Month 1-12)
─────────────────────────────
Everything in PHP. Validate product-market fit.

Phase 2: Rust Parser (Month 12-18, if needed)
─────────────────────────────────────────────
- Rust parser with PHP FFI
- 10-100x parse speed improvement
- WASM build for browser

Phase 3: Rust Runtime (Month 18-24, if needed)
──────────────────────────────────────────────
- Rust event processing engine
- PHP becomes orchestration layer only
- Bindings still in any language

8.3 FFI Integration ​

php
// PHP calling Rust parser via FFI
$parser = FFI::cdef("
    typedef struct ParseResult { ... } ParseResult;
    ParseResult* parse_flow(const char* content);
", "libeventflow.so");

$result = $parser->parse_flow($flowContent);

9. Implementation Roadmap (Detailed) ​

Based on the existing documentation and proposals, here's a comprehensive implementation plan.

Phase 0: Pre-Development (Week 1-2) ​

Goal: Set up infrastructure and validate architecture

  • [ ] Set up monorepo structure (Laravel package + docs)
  • [ ] Define grammar specification (finalize DSL syntax)
  • [ ] Create test fixtures (example .flow files from docs)
  • [ ] Set up CI/CD pipeline
  • [ ] Create development environment (Docker)

Phase 1: Parser & AST (Weeks 3-6) ​

Goal: Parse .flow files into Abstract Syntax Tree

Input: order.flow → Parser → AST → Validation

Tasks:

  • [ ] Implement lexer (tokenize symbols: @, :, #, $, ?, =)
  • [ ] Implement PEG grammar (Pest PHP)
  • [ ] Build AST nodes (Machine, Scenario, Event, Guard, Action, etc.)
  • [ ] Implement syntax validation
  • [ ] Implement semantic validation (undefined references, type checking)
  • [ ] Create helpful error messages with line numbers

Deliverable: eventflow parse order.flow --format=json

Phase 2: Core Runtime (Weeks 7-12) ​

Goal: Execute parsed flow files

2.1 State Machine Engine

  • [ ] Machine instance lifecycle (create, load, persist)
  • [ ] State management (#pending, #paid, etc.)
  • [ ] State transition logic
  • [ ] Event sourcing foundation (event store)

2.2 Event Processing

  • [ ] Event handler resolution (on :event from @actor)
  • [ ] Guard evaluation (? condition, ?? or-guard)
  • [ ] Action execution (state changes, context updates)
  • [ ] Event emission (emit :event to @machine)

2.3 Context System

  • [ ] Context variable management ($total, $items)
  • [ ] Type inference and validation
  • [ ] Context operations (becomes, increases by, adds, removes)

Deliverable: eventflow run order.flow --event=checkout

Phase 3: Binding System (Weeks 13-16) ​

Goal: Connect DSL to PHP implementations

  • [ ] Define binding interface (Guard, Action, Assertion)
  • [ ] Implement PHP attribute discovery (#[Guard('...')])
  • [ ] Pattern matching with placeholders ({string}, {number})
  • [ ] Auto-discovery from configured paths
  • [ ] Binding registry and caching
  • [ ] Missing binding detection and scaffolding

Deliverable: eventflow binding:list, eventflow binding:scaffold "cart is not empty"

Phase 4: Testing Framework (Weeks 17-22) ​

Goal: Make scenarios executable tests

4.1 Test Runner

  • [ ] Scenario parser (given, on, expect blocks)
  • [ ] Given statement execution (setup bindings)
  • [ ] Event sequence execution
  • [ ] Assertion evaluation (= statements)

4.2 Test Reporting

  • [ ] Test result output (pass/fail/skip)
  • [ ] Coverage calculation (states, events, guards)
  • [ ] Integration with Pest PHP

4.3 Advanced Testing

  • [ ] Delta-based variations (testing.test.flow)
  • [ ] Parameterized tests (data tables)
  • [ ] assume/observe blocks

Deliverable: eventflow test order.flow, eventflow test order.flow --coverage

Phase 5: Diagram Generation (Weeks 23-26) ​

Goal: Auto-generate visualizations

  • [ ] Lane diagram generation (actors, events flow)
  • [ ] State diagram generation (states, transitions)
  • [ ] Mermaid output format
  • [ ] SVG output format
  • [ ] Interactive HTML output (zoomable, clickable)

Deliverable: eventflow diagram order.flow --type=lane --format=svg

Phase 6: CLI Polish & DX (Weeks 27-30) ​

Goal: Developer-friendly tooling

  • [ ] eventflow init - Project scaffolding
  • [ ] eventflow validate - Syntax + semantic validation
  • [ ] eventflow watch - File watcher with auto-reload
  • [ ] eventflow doctor - Environment health check
  • [ ] Error messages with suggestions
  • [ ] Shell completion (bash, zsh)

Deliverable: Complete CLI toolkit

Phase 7: Laravel Integration Package (Weeks 31-34) ​

Goal: Seamless Laravel integration

  • [ ] Service provider registration
  • [ ] Artisan commands (php artisan eventflow:*)
  • [ ] Config file publishing
  • [ ] Route generation for (api) events
  • [ ] Middleware for event authentication
  • [ ] Integration with Laravel Queue (Horizon)
  • [ ] Integration with Laravel Event system

Deliverable: composer require eventflow/laravel

Phase 8: Open Source Release (Weeks 35-36) ​

Goal: Public launch

  • [ ] Documentation website (VitePress - already exists)
  • [ ] GitHub repository setup
  • [ ] README, CONTRIBUTING, LICENSE
  • [ ] Packagist release
  • [ ] Launch blog post
  • [ ] Community setup (Discord, GitHub Discussions)

SaaS Development Phases ​

After open source core is stable:

SaaS Phase 1: Foundation (Months 1-2 after OSS) ​

  • [ ] Laravel application setup (Breeze, Sanctum)
  • [ ] User authentication
  • [ ] Project CRUD (name, description, flow files)
  • [ ] File upload and storage (S3)
  • [ ] Basic dashboard UI (Inertia + Vue)

SaaS Phase 2: Cloud Diagrams (Month 3) ​

  • [ ] Server-side diagram rendering
  • [ ] Shareable public links
  • [ ] Embed codes
  • [ ] PDF export
  • [ ] Rate limiting (free tier limits)

SaaS Phase 3: Online Editor (Months 4-5) ​

  • [ ] Monaco editor integration
  • [ ] Syntax highlighting (TextMate grammar exists)
  • [ ] Real-time validation
  • [ ] Auto-complete (symbols, references)
  • [ ] Split view (code + diagram)

SaaS Phase 4: Billing (Month 6) ​

  • [ ] Stripe integration (Laravel Cashier)
  • [ ] Subscription plans
  • [ ] Usage metering
  • [ ] Invoice generation
  • [ ] Free trial handling

SaaS Phase 5: Analytics (Months 7-8) ​

  • [ ] Metrics collection agent (see ANALYTICS_PROPOSAL)
  • [ ] Cloud-hosted metrics dashboard
  • [ ] Funnel visualization
  • [ ] Export capabilities

SaaS Phase 6: Team Collaboration (Months 9-10) ​

  • [ ] Team workspaces
  • [ ] Member invitations
  • [ ] Role-based permissions
  • [ ] Version history (Git-like)
  • [ ] Comments and annotations

9.1 Critical Path Dependencies ​

Parser ──► Runtime ──► Bindings ──► Testing ──► CLI
                          │
                          ▼
                      Diagrams
                          │
                          ▼
                    Laravel Pkg
                          │
                          ▼
                    OSS Release
                          │
                          ▼
                   SaaS Features

9.2 Risk Mitigation ​

RiskMitigation
Parser complexityStart with subset, expand iteratively
Performance issuesProfile early, Rust migration path ready
Feature creepMVP first, iterate based on feedback
Binding complexityPHP-only first year
SaaS infra costServerless (Vapor) to scale with usage

10. Decision Summary ​

DecisionChoiceRationale
Core languagePHP (Laravel)Author expertise, fastest MVP
Binding languagesPHP first, others laterFocus on perfecting one
SaaS modelFreemiumOpen source goodwill + revenue
InfrastructureLaravel VaporManaged, scalable, Laravel-native
Future performanceRust (optional)FFI/WASM when needed
FrontendInertia.js + VueFull-stack Laravel happiness

11. Open Questions ​

  1. Should bindings use HTTP or gRPC for cross-language communication?
  2. What's the minimum viable analytics for Pro tier?
  3. Should we offer annual pricing discount?
  4. Is on-premise option worth the support overhead?
  5. What should be the pricing for different markets (e.g., Turkey vs US)?

12. Appendix: Competitor Analysis ​

ProductApproachPricing
XStateJS library onlyFree (OSS)
TemporalFull platform$0.25/action
AWS Step FunctionsCloud only$0.025/transition
EventFlowDSL + SaaSFreemium

Differentiation: Natural language DSL, any-language bindings, open source core.


13. Appendix: Language Analysis ​

Why Not Start With TypeScript? ​

While TypeScript would be ideal for:

  • Widest developer reach
  • Best tooling ecosystem
  • Full-stack capability

The author's expertise is PHP/Laravel, making PHP 2-3x faster to ship initially.

Why Not Erlang/Elixir? ​

EventFlow's concepts (Actor model, message passing, isolated state) align perfectly with Erlang/OTP. However:

  • Narrow developer pool
  • Harder to hire
  • Less mainstream adoption

The Pragmatic Choice ​

Ship in PHP first (author's strength), then:

  1. Prove product-market fit
  2. Add other language bindings based on demand
  3. Migrate performance-critical parts to Rust if needed

"The best language is the one that ships."

Released under the MIT License.