Polyglot Design (Python/TS)
Relevant source files
The following files were used as context for generating this wiki page:
The bubus project implements a cross-language event bus architecture designed for seamless interoperability between Python and TypeScript (TS) environments. This design ensures that event structures, validation logic, and execution states remain consistent regardless of which language environment originates or processes an event.
The core of this polyglot design relies on a unified runtime refactor that aligns middleware, context management, and error taxonomy across both implementations. By utilizing JSON Schema as the intermediary for type definitions, the system allows complex Pydantic models in Python to be validated against Zod schemas in TypeScript, and vice-versa, maintaining strict type safety during "round-trip" operations.
Sources: TODO_ts.md:1-15, TODO_python.md:1-15, bubus/jsonschema.py:300-315
Cross-Language Data Architecture
The interoperability between Python and TypeScript is achieved through a standardized serialization format and shared semantic rules for event processing.
Shared Event Structure
All events, whether in Python or TS, share a common set of metadata fields. This allows an EventBus in one language to rehydrate a bus state or event queue produced by the other.
| Field | Description |
|---|---|
event_id | Unique UUIDv7 identifier for the event. |
event_type | The string identifier for the event class. |
event_version | Schema version tag for migration-friendly handling. |
event_path | List of bus labels (name#id) the event has traversed. |
event_result_type | JSON Schema representation of the expected return type. |
event_status | Current lifecycle state: pending, started, or completed. |
Sources: bubus-ts/src/base_event.ts:24-46, tests/test_python_to_ts_roundrip.py:220-235
Schema Interoperability (JSON Schema)
To maintain type safety across languages, the system translates Python Pydantic models and TypeScript Zod schemas into a neutral JSON Schema format during serialization.
- Python to TS: Python uses
pydantic_model_to_json_schemato generate JSON Schema definitions. TS rehydrates these into Zod-like validators. - TS to Python: TS produces JSON objects which Python validates using
pydantic_model_from_json_schemato reconstruct dynamic Pydantic models.
Sources: bubus/jsonschema.py:215-230, tests/test_python_to_ts_roundrip.py:240-260, bubus-ts/tests/ts_to_python_roundtrip.test.ts:315-330
Execution Lifecycle Alignment
The project enforces a unified runtime trace to ensure behavior-safe refactoring and consistent event execution.
This diagram shows the synchronized execution flow that both Python and TS runtimes must follow.
Sources: TODO_ts.md:44-65, TODO_python.md:46-68
Semantic Decisions
Both implementations have been aligned on several critical semantic rules:
- Hard Timeouts:
event_timeoutserves as a hard cap across all handlers. - First-Winner Semantics: In
first()mode, a valid winner is the first result that is non-error, non-BaseEvent, and non-null/undefined. - Queue-Jumping: The immediate execution path remains lock-driven and must preserve re-entrancy safety across language bridges.
Sources: TODO_ts.md:17-26, TODO_python.md:17-26
Unified Error Taxonomy
A shared error taxonomy is used to ensure that failures in one language environment are correctly interpreted by another. Both Python and TS implementations are required to map terminal handler paths to these four classes:
- EventHandlerCancelledError: The handler was cancelled before starting.
- EventHandlerResultSchemaError: The handler returned a value that failed JSON Schema validation.
- EventHandlerTimeoutError: The handler exceeded its allocated execution time.
- EventHandlerAbortedError: The handler was forcibly stopped (e.g., due to a hard event-level timeout).
Sources: TODO_ts.md:195-200, TODO_python.md:200-205, bubus-ts/src/base_event.ts:13-14
Inter-Process Communication (IPC) Round-Trips
Interoperability is verified through "round-trip" tests where events or entire bus states are passed between Node.js and Python processes.
Event and Bus Rehydration
The system supports full state rehydration. A TS EventBus can be serialized to JSON, passed to a Python process, and re-validated as a Python EventBus. This includes:
- The
event_historymap. - The
pending_event_queue. - All registered
handlers(though function references must be re-bound post-hydration).
Sequence of a cross-language bus state round-trip.
Sources: tests/test_python_to_ts_roundrip.py:350-380, bubus-ts/tests/ts_to_python_roundtrip.test.ts:400-430
Code Example: Validating Cross-Language Result Schemas
The following logic illustrates how TS validates results against a schema defined in Python (and vice versa) using rehydrated validators.
// TS side rehydrating a Python-defined schema
const original_schema = fromJsonSchema(original_schema_json);
const candidate_schema = fromJsonSchema(candidate_schema_json);
for (const result of valid_results) {
const original_ok = original_schema.safeParse(result).success;
const candidate_ok = candidate_schema.safeParse(result).success;
assert.equal(candidate_ok, original_ok, "Schema decision mismatch");
}
Sources: bubus-ts/tests/ts_to_python_roundtrip.test.ts:45-65, tests/test_python_to_ts_roundrip.py:100-115
Conclusion
The polyglot design of bubus achieves environment-agnostic event processing by strictly standardizing the lifecycle and serialization of events. By enforcing a shared error taxonomy and utilizing JSON Schema as a type-safe bridge, the project allows developers to build distributed systems where Python and TypeScript components interact with the same reliability as they would within a single-language runtime.
Sources: TODO_ts.md:230-245, TODO_python.md:235-245